过滤器做为web.xml中重要的一部分,有着至关高的出场率,SpringBoot会默认注册几个Filterhtml
ApplicationContextHeaderFilterjava
CharacterEncodingFilterweb
若是添加了Security依赖的话会加入SpringSecurityFilterChainspring
若是加入Actuator依赖的话就会加入WebRequestTraceFilterbootstrap
咱们若是本身要实现本身的Filter的话,须要实现Filter并实现其中的方法api
同时要利用JavaConfig的方法来配置,通常状况下须要编写@Bean注解的返回值为FilterRegistrationBean的方法来实现JavaBean的注册tomcat
具体实现以下oracle
须要注意的是此方法须要在被@Configuration注解的配置类中app
若是以为Java代码的方式比较繁琐的话能够采用注解方式注册Filter,具体实现方式是在Filter实现类加入@WebFilter注解spring-boot
例如
而后在SpringBootApplication类上添加@ServletComponentScan
咱们采用JavaConfig的形式实现了Filter的注册,经过向上追溯得知FilterRegistrationBean的层级结构以下
ServletContextInitializer
RegistrationBean
AbstractFilterRegistrationBean
FilterRegistrationBean
经查阅SpringBoot文档发现针对ServletContextInitializer的描述以下
Interface used to configure a Servlet 3.0+
context
programmatically. UnlikeWebApplicationInitializer
, classes that implement this interface (and do not implementWebApplicationInitializer
) will not be detected bySpringServletContainerInitializer
and hence will not be automatically bootstrapped by the Servlet container.This interface is primarily designed to allow
ServletContextInitializer
s 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的支持与Filter大同小异,一样也是支持两种方法进行注册
JavaConfig的话不一样的是Servlet须要的是ServletRegistrationBean,而Listener须要的是ServletListenerRegistrationBean
注解的话则分别是经过@WebServlet、@WebListener进行注解
至于注册管理过程则基本与Filter相同