在 spring boot
中,只需要创建一个 bean
实现 filter
接口,spring boot
就会把这个 filter
加入到 servlet
容器中。
在实际使用中,常用的接口就是 OncePerRequestFilter
和 OrderedFilter
, 所以来看看 spring boot
是如何适配 servlet
规范。
创建 WebServer
源码位置: org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#onRefresh
1
2
3
4
5
6
7
8
9
10
11
12
// 在 spring 容器刷新时,会调用此方法
@Override
protected void onRefresh () {
super . onRefresh ();
try {
// 创建 webServer
createWebServer ();
}
catch ( Throwable ex ) {
throw new ApplicationContextException ( "Unable to start web server" , ex );
}
}
源码位置: org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#createWebServer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 创建 webServer
private void createWebServer () {
WebServer webServer = this . webServer ;
ServletContext servletContext = getServletContext ();
if ( webServer == null && servletContext == null ) {
StartupStep createWebServer = this . getApplicationStartup (). start ( "spring.boot.webserver.create" );
// 获取工厂类,比如有 tomcat,jetty 的实现, 这个省略了。
ServletWebServerFactory factory = getWebServerFactory ();
createWebServer . tag ( "factory" , factory . getClass (). toString ());
// 创建 webServer,重点看这个
this . webServer = factory . getWebServer ( getSelfInitializer ());
createWebServer . end ();
// 注册钩子
getBeanFactory (). registerSingleton ( "webServerGracefulShutdown" ,
new WebServerGracefulShutdownLifecycle ( this . webServer ));
getBeanFactory (). registerSingleton ( "webServerStartStop" ,
new WebServerStartStopLifecycle ( this , this . webServer ));
}
...
}
源码位置: org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#getSelfInitializer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 获取 ServletContextInitializer
private org . springframework . boot . web . servlet . ServletContextInitializer getSelfInitializer () {
return this :: selfInitialize ;
}
private void selfInitialize ( ServletContext servletContext ) throws ServletException {
prepareWebApplicationContext ( servletContext );
registerApplicationScope ( servletContext );
WebApplicationContextUtils . registerEnvironmentBeans ( getBeanFactory (), servletContext );
// 初始化 ServletContextInitializer, 里面就包括 filter,servlet,listener
for ( ServletContextInitializer beans : getServletContextInitializerBeans ()) {
beans . onStartup ( servletContext );
}
}
// ServletContextInitializerBeans 的构造方法很重要
protected Collection < ServletContextInitializer > getServletContextInitializerBeans () {
return new ServletContextInitializerBeans ( getBeanFactory ());
}
ServletContextInitializerBeans 适配器
源码位置: org.springframework.boot.web.servlet.ServletContextInitializerBeans#ServletContextInitializerBeans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// ServletContextInitializerBeans 的构造函数
public ServletContextInitializerBeans ( ListableBeanFactory beanFactory ,
Class <? extends ServletContextInitializer > ... initializerTypes ) {
this . initializers = new LinkedMultiValueMap <> ();
this . initializerTypes = ( initializerTypes . length != 0 ) ? Arrays . asList ( initializerTypes )
: Collections . singletonList ( ServletContextInitializer . class );
// 适配 filter,servlet,listener,很重要
addServletContextInitializerBeans ( beanFactory );
// 适配 filter,servlet,很重要
addAdaptableBeans ( beanFactory );
// 排序 ServletContextInitializer
List < ServletContextInitializer > sortedInitializers = this . initializers . values (). stream ()
. flatMap (( value ) -> value . stream (). sorted ( AnnotationAwareOrderComparator . INSTANCE ))
. collect ( Collectors . toList ());
this . sortedList = Collections . unmodifiableList ( sortedInitializers );
logMappings ( this . initializers );
}
源码位置: org.springframework.boot.web.servlet.ServletContextInitializerBeans#addServletContextInitializerBeans
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
// 适配 filter,servlet,listener
private void addServletContextInitializerBeans ( ListableBeanFactory beanFactory ) {
for ( Class <? extends ServletContextInitializer > initializerType : this . initializerTypes ) {
for ( Entry < String , ? extends ServletContextInitializer > initializerBean : getOrderedBeansOfType ( beanFactory ,
initializerType )) {
addServletContextInitializerBean ( initializerBean . getKey (), initializerBean . getValue (), beanFactory );
}
}
}
private void addServletContextInitializerBean ( String beanName , ServletContextInitializer initializer ,
ListableBeanFactory beanFactory ) {
// 适配 servlet
if ( initializer instanceof ServletRegistrationBean ) {
Servlet source = (( ServletRegistrationBean <?> ) initializer ). getServlet ();
addServletContextInitializerBean ( Servlet . class , beanName , initializer , beanFactory , source );
}
// 适配 filter
else if ( initializer instanceof FilterRegistrationBean ) {
Filter source = (( FilterRegistrationBean <?> ) initializer ). getFilter ();
addServletContextInitializerBean ( Filter . class , beanName , initializer , beanFactory , source );
}
// 适配 filter
else if ( initializer instanceof DelegatingFilterProxyRegistrationBean ) {
String source = (( DelegatingFilterProxyRegistrationBean ) initializer ). getTargetBeanName ();
addServletContextInitializerBean ( Filter . class , beanName , initializer , beanFactory , source );
}
// 适配 listener
else if ( initializer instanceof ServletListenerRegistrationBean ) {
EventListener source = (( ServletListenerRegistrationBean <?> ) initializer ). getListener ();
addServletContextInitializerBean ( EventListener . class , beanName , initializer , beanFactory , source );
}
else {
addServletContextInitializerBean ( ServletContextInitializer . class , beanName , initializer , beanFactory ,
initializer );
}
}
源码位置: org.springframework.boot.web.servlet.ServletContextInitializerBeans#addAdaptableBeans
1
2
3
4
5
6
7
8
9
10
11
12
// 适配 filter,servlet
protected void addAdaptableBeans ( ListableBeanFactory beanFactory ) {
MultipartConfigElement multipartConfig = getMultipartConfig ( beanFactory );
// 适配 servlet
addAsRegistrationBean ( beanFactory , Servlet . class , new ServletRegistrationBeanAdapter ( multipartConfig ));
// 适配 filter
addAsRegistrationBean ( beanFactory , Filter . class , new FilterRegistrationBeanAdapter ());
for ( Class <?> listenerType : ServletListenerRegistrationBean . getSupportedTypes ()) {
addAsRegistrationBean ( beanFactory , EventListener . class , ( Class < EventListener > ) listenerType ,
new ServletListenerRegistrationBeanAdapter ());
}
}