過濾器做爲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相同