ServletContextInitializer添加 servlet filter listener springboot 2.1.3.RELEASE添加filter,servlet源码学习

ServletContextInitializer添加 servlet filter listener 

https://www.cnblogs.com/pomer-huang/p/9639322.html

springboot 2.1.3.RELEASE添加filter,servlet源码学习

 

Servlet规范中,通过ServeltContext来注册Filter、Servlet,这里分析Filter,Servlet是相同逻辑

springboot2.0中,我们通过

FilterRegistrationBean将指定得filter来实现ServeltContext注册filter

1
2
3
4
5
6
7
8
9
10
11
12
13
FilterRegistrationBean的实例化过程
 
public  FilterRegistrationBean(T filter, ServletRegistrationBean... servletRegistrationBeans) {
         super (servletRegistrationBeans);
         Assert.notNull(filter,  "Filter must not be null" );
         this .filter = filter;
}
 
super 的实例化
AbstractFilterRegistrationBean(ServletRegistrationBean... servletRegistrationBeans) {
         Assert.notNull(servletRegistrationBeans,  "ServletRegistrationBeans must not be null" );
         Collections.addAll( this .servletRegistrationBeans, servletRegistrationBeans);
}

可知FilterRegistrationBean得实例化过程就是将Filter保存到servletRegistrationBeans(一个set)中

再分析FilterRegistrationBean类

FilterRegistrationBean的父类是一个ServletContextInitializer,他有一个方法onStartup(ServletContext servletContext)
其结果最终会调用
servletContext.addFilter(this.getOrDeduceName(filter), filter)
现在看看ServletContextInitializer.onStartup的调用地方
1
2
3
4
5
6
7
8
9
10
11
12
springboot启动
new  SpringApplication(XXApplication. class ).run(XXApplication. class ,args)
调用
refreshContext(context); -> refresh(context); -> ((AbstractApplicationContext) applicationContext).refresh();
-> ServletWebServerApplicationContext.onRefresh(); -> createWebServer();
 
WebServer webServer =  this .webServer;
ServletContext servletContext = getServletContext();
if  (webServer ==  null  && servletContext ==  null ) {
     ServletWebServerFactory factory = getWebServerFactory();
     this .webServer = factory.getWebServer(getSelfInitializer());
}

再分析getSelfInitializer方法

1
2
3
4
prepareWebApplicationContext(servletContext);
         registerApplicationScope(servletContext);
         WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(),servletContext);
         for  (ServletContextInitializer beans :getServletContextInitializerBeans()) {              
       //调用ServletContextInitializer的onStartup方法
1
beans.onStartup(servletContext); }
-> getServletContextInitializerBeans()
1
2
->  new  ServletContextInitializerBeans(getBeanFactory())
-> addAdaptableBeans(beanFactory)

 

1
2
3
4
5
6
7
8
addAdaptableBeans(ListableBeanFactory beanFactory) 代码如下:
MultipartConfigElement multipartConfig = getMultipartConfig(beanFactory);
//将servlet类的bean包装为ServletRegistrationBean
addAsRegistrationBean(beanFactory, Servlet. class , new  ServletRegistrationBeanAdapter(multipartConfig));
//将Filter的bean包装为FilterRegistrationBean
addAsRegistrationBean(beanFactory, Filter. class , new  FilterRegistrationBeanAdapter());
for  (Class<?> listenerType : ServletListenerRegistrationBean.getSupportedTypes())
{         
addAsRegistrationBean(beanFactory, EventListener. class ,(Class<EventListener>) listenerType, new  ServletListenerRegistrationBeanAdapter());
}

 这里提一下,如果Servlet的bean实例名为dispatcherServlet,且该实例在seen集合中(seen集合为自定义配置的实例,通过ServletContextInitializerBeans.addServletContextInitializerBean入口可以查看源码),则设置默认值为  /

1
2
3
4
5
6
7
String url = (totalNumberOfSourceBeans !=  1 ) ?  "/"  + name +  "/"  "/" ;
if  (name.equals(DISPATCHER_SERVLET_NAME)) {
     url =  "/" // always map the main dispatcherServlet to "/"
}
ServletRegistrationBean<Servlet> bean =  new  ServletRegistrationBean<>(source,url); 
bean.setName(name);
bean.setMultipartConfig( this .multipartConfig);
return  bean;

 

总结:springboot启动时,会将所有的 FilterRegistrationBean、ServletRegistrationBean以及被spring管理的Servlet和Filter的实例,通过          ServletContext注册Servlet以及Filter

Servlet规范中,通过ServeltContext来注册Filter、Servlet,这里分析Filter,Servlet是相同逻辑

springboot2.0中,我们通过

FilterRegistrationBean将指定得filter来实现ServeltContext注册filter

1
2
3
4
5
6
7
8
9
10
11
12
13
FilterRegistrationBean的实例化过程
 
public  FilterRegistrationBean(T filter, ServletRegistrationBean... servletRegistrationBeans) {
         super (servletRegistrationBeans);
         Assert.notNull(filter,  "Filter must not be null" );
         this .filter = filter;
}
 
super 的实例化
AbstractFilterRegistrationBean(ServletRegistrationBean... servletRegistrationBeans) {
         Assert.notNull(servletRegistrationBeans,  "ServletRegistrationBeans must not be null" );
         Collections.addAll( this .servletRegistrationBeans, servletRegistrationBeans);
}

可知FilterRegistrationBean得实例化过程就是将Filter保存到servletRegistrationBeans(一个set)中

再分析FilterRegistrationBean类

FilterRegistrationBean的父类是一个ServletContextInitializer,他有一个方法onStartup(ServletContext servletContext)
其结果最终会调用
servletContext.addFilter(this.getOrDeduceName(filter), filter)
现在看看ServletContextInitializer.onStartup的调用地方
1
2
3
4
5
6
7
8
9
10
11
12
springboot启动
new  SpringApplication(XXApplication. class ).run(XXApplication. class ,args)
调用
refreshContext(context); -> refresh(context); -> ((AbstractApplicationContext) applicationContext).refresh();
-> ServletWebServerApplicationContext.onRefresh(); -> createWebServer();
 
WebServer webServer =  this .webServer;
ServletContext servletContext = getServletContext();
if  (webServer ==  null  && servletContext ==  null ) {
     ServletWebServerFactory factory = getWebServerFactory();
     this .webServer = factory.getWebServer(getSelfInitializer());
}

再分析getSelfInitializer方法

1
2
3
4
prepareWebApplicationContext(servletContext);
         registerApplicationScope(servletContext);
         WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(),servletContext);
         for  (ServletContextInitializer beans :getServletContextInitializerBeans()) {              
       //调用ServletContextInitializer的onStartup方法
1
beans.onStartup(servletContext); }
-> getServletContextInitializerBeans()
1
2
->  new  ServletContextInitializerBeans(getBeanFactory())
-> addAdaptableBeans(beanFactory)

 

1
2
3
4
5
6
7
8
addAdaptableBeans(ListableBeanFactory beanFactory) 代码如下:
MultipartConfigElement multipartConfig = getMultipartConfig(beanFactory);
//将servlet类的bean包装为ServletRegistrationBean
addAsRegistrationBean(beanFactory, Servlet. class , new  ServletRegistrationBeanAdapter(multipartConfig));
//将Filter的bean包装为FilterRegistrationBean
addAsRegistrationBean(beanFactory, Filter. class , new  FilterRegistrationBeanAdapter());
for  (Class<?> listenerType : ServletListenerRegistrationBean.getSupportedTypes())
{         
addAsRegistrationBean(beanFactory, EventListener. class ,(Class<EventListener>) listenerType, new  ServletListenerRegistrationBeanAdapter());
}

 这里提一下,如果Servlet的bean实例名为dispatcherServlet,且该实例在seen集合中(seen集合为自定义配置的实例,通过ServletContextInitializerBeans.addServletContextInitializerBean入口可以查看源码),则设置默认值为  /

1
2
3
4
5
6
7
String url = (totalNumberOfSourceBeans !=  1 ) ?  "/"  + name +  "/"  "/" ;
if  (name.equals(DISPATCHER_SERVLET_NAME)) {
     url =  "/" // always map the main dispatcherServlet to "/"
}
ServletRegistrationBean<Servlet> bean =  new  ServletRegistrationBean<>(source,url); 
bean.setName(name);
bean.setMultipartConfig( this .multipartConfig);
return  bean;

 

总结:springboot启动时,会将所有的 FilterRegistrationBean、ServletRegistrationBean以及被spring管理的Servlet和Filter的实例,通过          ServletContext注册Servlet以及Filter

猜你喜欢

转载自www.cnblogs.com/kelelipeng/p/11494005.html