源码分析:Tomcat - Filter - RequestContextHolder 上下文请求

1. Filter - RequestContextHolder 上下文请求
2. Filter - SpringBoot桥接原理

前言

1
2
3
问1:为什么我在 Controller 方法内部可以获取 RequestContextHolder 上下文请求?

问2:这个上下文会内存泄漏吗?

阶段1:SpringBoot引导 - Tomcat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
SpringApplication#run
AbstractApplicationContext#refresh
public void refresh(){
// ...
try {
// ...
finishBeanFactoryInitialization(beanFactory);
finishRefresh();// ***
}
// ...
}
AbstractApplicationContext#finishRefresh
// getLifecycleProcessor().onRefresh();
// DefaultLifecycleProcessor#doStart
// WebServerStartStopLifecycle#start // 实现 Lifecycle#start
// AbstractProtocol#start
// NioEndpoint#startInternal
// 1. 创建线程池 - 用于处理请求
// createExecutor();
// AbstractEndpoint#createExecutor

// 2. Selector 接收HTTP请求,提交任务 -> 线程池
// poller = new Poller();// Selector.open();
// pollerThread.start();// NioEndpoint.Poller#run
// selector.selectedKeys()
// processKey(sk, socketWrapper);
// sc = createSocketProcessor(socketWrapper, event);// NioEndpoint#createSocketProcessor
// executor.execute(sc);// 参考下面

阶段2:Tomcat处理请求 - Filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// NioEndpoint.SocketProcessor#doRun
// ↓ state = getHandler().process(socketWrapper, event);
// ↓↓ state = processor.process(wrapper, status);
// ↓↓↓ state = service(socketWrapper);// OPEN_READ
// ↓↓↓↓ getAdapter().service(request, response);// Http11Processor#service
// ↓↓↓↓↓ connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);// CoyoteAdapter#service
// ↓↓↓↓↓↓ host.getPipeline().getFirst().invoke(request, response);
// ...
// StandardWrapperValve#invoke
// ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
// addFilter
for (FilterMap filterMap : filterMaps) {
if (!matchFiltersURL(filterMap, requestPath)) {
continue;
}
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) context.findFilterConfig(filterMap.getFilterName());
filterChain.addFilter(filterConfig);
}
// filterChain.doFilter(request.getRequest(), response.getResponse());
// internalDoFilter(request, response);
private void internalDoFilter(ServletRequest request, ServletResponse response){

// 1、调用下一个 filter
if (pos < n) {
ApplicationFilterConfig filterConfig = filters[pos++];
//...
Filter filter = filterConfig.getFilter();
filter.doFilter(request, response, this);
//...
return;
}

// 2、责任链结束,调用 servlet
servlet.service(request, response);
}

// RequestContextFilter#doFilterInternal // 上下文拦截器 // 获取上下文信息
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain){

ServletRequestAttributes attributes = new ServletRequestAttributes(request, response);
initContextHolders(request, attributes);// set

try {
filterChain.doFilter(request, response);
}
finally {
resetContextHolders();// remove
//...
}
}

阶段3:MVC引导 - controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// HttpServlet#service
// ...
// FrameworkServlet#processRequest // ServletRequestAttributes - 再置
protected final void processRequest(HttpServletRequest request, HttpServletResponse response){

// ...

// 旧的
RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
// 新的
ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);
// ...
// 放入新的
initContextHolders(request, localeContext, requestAttributes);

try {
// controller
doService(request, response);
}
// ...
finally {
// 恢复旧的
resetContextHolders(request, previousLocaleContext, previousAttributes);
// ...
}
}
// ...
// DispatcherServlet#doDispatch
// # 调用controller方法
// mv = ha.handle(processedRequest, response, mappedHandler.getHandler());