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+ context programmatically. Unlike WebApplicationInitializer, classes that implement this interface (and do not implement WebApplicationInitializer) will not be detected by SpringServletContainerInitializer and 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相同

 

参考:https://www.cnblogs.com/jpfss/p/9045916.html