文章目录
了解了SpringBoot中Tomcat的启动过程,本文来看一下SpringBoot中如何向Tomcat中添加Servlet、Filter、Listener.
自定义Servlet、Filter、Listener
Spring容器中声明ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean
@ServletComponentScan注解和@WebServlet、@WebFilter以及@WebListener注解的配合使用
@ServletComponentScan
注解启用ImportServletComponentScanRegistrar
类,是个ImportBeanDefinitionRegistrar
接口的实现类,会被Spring容器所解析。ServletComponentScanRegistrar
内部会解析@ServletComponentScan
注解,然后会在Spring容器中注册ServletComponentRegisteringPostProcessor
,是个BeanFactoryPostProcessor
,会去解析扫描出来的类是不是有@WebServlet、@WebListener、@WebFilter
这3种注解,有的话把这3种类型的类转换成ServletRegistrationBean、FilterRegistrationBean或者ServletListenerRegistrationBean
,然后让Spring容器去解析:
在Spring容器中声明Servlet、Filter或者Listener
相比SpringMVC中通过在web.xml中配置DispatcherServlet
来说,SpringBoot中配置Servlet很简单,但是底层却不简单。
ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean三个类
ServletRegistrationBean
FilterRegistrationBean
ServletListenerRegistrationBean
RegistrationBean
ServletContextInitializer
是 Servlet 容器初始化的时候,提供的初始化接口。所以,Servlet 容器初始化会获取并触发所有的ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean
实例中onStartup方法。
触发这些类的onStartup方法的方式:
接下来看一下FilterRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean
实例是何时加入到Initializers
集合中的。
Servlet容器的启动
在EmbeddedWebApplicationContext
中获取嵌入式的Servlet容器工厂,并通过工厂来获取Servlet容器的时候,会先通过getSelfInitializer()
获取到所有的Initializer
,传入Servlet容器中,看一下getSelfInitializer()
方法:
Servlet容器启动的时候,会调用这个ServletContextInitializer
对象的onStartup方法,onStartup中的逻辑也就是selfInitialize
方法,并将Servlet上下文对象传进去了。
selfInitialize
先获取所有的ServletContextInitializer
实现类,然后遍历执行所有ServletContextInitializer
的onStartup方法。
获取所有的ServletContextInitializer
首先来看一下getServletContextInitializerBeans
方法:
ServletContextInitializerBeans
对象是对ServletContextInitializer
的一种包装:
第8行调用addServletContextInitializerBeans
方法:
调用addServletContextInitializerBean
方法:
构造器中的另外一个方法:addAdaptableBeans(beanFactory)
两个适配器:
Servlet.class、Filter.class都添加到List<ServletContextInitializer> sortedList
这个集合中去了,接着就是遍历这个集合,执行其onStartup方法。
ServletContextInitializer的onStartup方法
ServletRegisterationBean
AbstractFilterRegistrationBean
DispatcherServletAutoConfiguration
SpringBoot在自动配置SpringMVC的时候,会自动注册SpringMVC前端控制器:DispatcherServlet
,该控制器主要在DispatcherServletAutoConfiguration自动配置类中进行注册,DispatcherServlet
是SpringMVC中的核心分发器,DispatcherServletAutoConfiguration也在spring.factories中配置了。
DispatcherServletConfiguration
ServletRegistrationBean
的逻辑为:在Tomcat启动的时候,会获取所有的ServletRegistrationBean,并执行其中的onstartup方法,将DispatcherServlet注册到Servlet容器中,这样就类似原来的web.xml中配置的dispatcherServlet。所以只要导入了spring-boot-starter-web
这个starter,SpringBoot就有了Tomcat容器,并且往Tomcat容器中注册了DispatcherSevlet
对象,这样就能接收我们的请求了。
感谢并参考:
https://www.cnblogs.com/java-chen-hao/p/11842611.html