Servlet容器的扩展机制
1 |
|
1 |
|
创建 ServletWebServerApplicationContext
AbstractApplicationContext.refresh() -> onRefresh() -> createWebServer() -> selfInitialize() 这里会读取 beanFactory 自动配置配类
DispatcherServletAutoConfiguration-> DispatcherServletRegistrationBean (底层实现接口
ServletContextInitializer)-> 执行 onStartup() -> 导入DispacherServlet
在第一次访问到 Servlet 时,调用 init() -> 加载HandlerMapping、HandlerAdpter
1 |
|
tip
Spring MVC 的配置(默认值):
spring: mvc: servlet: load-on-startup: 2
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
52
53
54
55
56
57
58
59
60
61
*
* servlet init 方法的调用时机,依赖 load-on-startup的配置信息
* init 方法是随 Servlet 实例化而被调用的,因为 load-on-startup 就是用来设置 Servlet 实例化时间的。
* 因此,init 方法执行的时刻有两种:
* (1) load-on-startup 的值大于等于0,则伴随 Servlet 实例化后执行。
* (2) load-on-startup 的值小于0 或者 不配置, 则在第一次 Servlet 请求的时候执行。
### tips
###### WebMvcAutoConfiguration
* 静态内部类 `EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration` 用来 注册 DispatcherServlet 各个handler (RequestMappingHandlerMapping)
```java
@Bean
@Primary
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
// Must be @Primary for MvcUriComponentsBuilder to work
return super.requestMappingHandlerMapping(contentNegotiationManager, conversionService,
resourceUrlProvider);
}Controller 在注入 Bean 以后,什么时候放入 RequestMappingHandlerMapping.mappingRegistry
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
RequestMappingHandlerMapping extends AbstractHanlerMapping
AbstractHandlerMethodMapping implements InitializingBean
在 Bean 生命周期 afterPropertiesSet() 方法 注入 Controller 中的 Method
重写 RequestMappingHandlerMapping 中的 isHandler 方法即可注入其他注解或者类型的Bean
**/
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}创建 DispatcherServlet (
DispatcherServletConfiguration
)
1 |
|
- 通过 DispatcherServletRegistrationBean 注入
DispatcherServlet
,原理: RegistrationBean (注册 servlet 3.0+) 实现了ServletContextInitializer
接口 servletContext 初始化生命周期方法