Filter
过滤器作为web.xml中重要的一部分,有着相当高的出场率,SpringBoot会默认注册几个Filter
ApplicationContextHeaderFilter
CharacterEncodingFilter
如果添加了Security依赖的话会加入SpringSecurityFilterChain
如果加入Actuator依赖的话就会加入WebRequestTraceFilter
实现自己的Filter
JavaConfig注册Bean
我们如果自己要实现自己的Filter的话,需要实现Filter并实现其中的方法
同时要利用JavaConfig的方法来配置,一般情况下需要编写@Bean注解的返回值为FilterRegistrationBean的方法来实现JavaBean的注册
具体实现如下
需要注意的是此方法需要在被@Configuration注解的配置类中
@WebFilter+@ServletComponentScan
如果觉得Java代码的方式比较繁琐的话可以采用注解方式注册Filter,具体实现方式是在Filter实现类加入@WebFilter注解
例如
然后在SpringBootApplication类上添加@ServletComponentScan
Filter的注册原理
我们采用JavaConfig的形式实现了Filter的注册,通过向上追溯得知FilterRegistrationBean的层级结构如下
ServletContextInitializer
RegistrationBean
AbstractFilterRegistrationBean
FilterRegistrationBean
经查阅SpringBoot文档发现针对ServletContextInitializer的描述如下
Interface used to configure a Servlet 3.0+
contextprogrammatically. UnlikeWebApplicationInitializer, classes that implement this interface (and do not implementWebApplicationInitializer) will not be detected bySpringServletContainerInitializerand hence will not be automatically bootstrapped by the Servlet container.This interface is primarily designed to allow
ServletContextInitializers to be managed by Spring and not the Servlet container.For configuration examples see
WebApplicationInitializer.
既然是由SpringBoot进行管理而不是由Servlet容器管理,那么基本可以确定是由SpringBoot进行管理
在org.springframework.boot.context.embedded.tomcat包中我们找到了答案
TomcatEmbeddedServletContainerFactory的一直向上继承了AbstractConfigurableEmbeddedServletContainer
并且维护了一个私有的List<ServletContextInitializer>变量,我们不难猜出,正是因为FilterRegistrationBean继承了ServletContextInitializer而实现了Filter的注册
为了进一步验证我们的猜测,在注册Filter的JavaConfig代码中打了断点跟踪一下
可以看到在启动过程中会获取类型为ServletContextInitializer的Bean
继续向下看在SpringBoot内嵌的Tomcat中的TomcatStarter类中也同样实现了ServletContextInitializer
并且在实现方法中执行了AbstractFilterRegistrationBean实现的onStartup方法
至此Filter注册成功
Servlet和Listener
Servlet与Listener的支持与Filter大同小异,同样也是支持两种方法进行注册
JavaConfig的话不同的是Servlet需要的是ServletRegistrationBean,而Listener需要的是ServletListenerRegistrationBean
注解的话则分别是通过@WebServlet、@WebListener进行注解
至于注册管理过程则基本与Filter相同



