<div class="htmledit_views">html
<h1 style="margin:0px;padding:0px;color:rgb(51,51,51);font-size:24px;font-weight:normal;line-height:1.25;border-bottom-color:rgb(204,204,204);font-family:Arial, sans-serif;"> Filter</h1> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 过滤器做为web.xml中重要的一部分,有着至关高的出场率,SpringBoot会默认注册几个Filter</p> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <strong>ApplicationContextHeaderFilter</strong></p> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <strong>CharacterEncodingFilter</strong></p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 若是添加了Security依赖的话会加入<strong>SpringSecurityFilterChain</strong></p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 若是加入Actuator依赖的话就会加入<strong>WebRequestTraceFilter</strong></p> <h3 style="margin:30px 0px 0px;padding:0px;color:rgb(51,51,51);font-size:16px;line-height:1.5;font-family:Arial, sans-serif;"> <strong>实现本身的Filter</strong></h3> <h4 style="margin:10px 0px 0px 30px;padding:0px;color:rgb(51,51,51);font-size:14px;line-height:1.42857;font-family:Arial, sans-serif;"> JavaConfig注册Bean</h4> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 咱们若是本身要实现本身的Filter的话,须要实现Filter并实现其中的方法</p> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 同时要利用JavaConfig的方法来配置,通常状况下须要编写@Bean注解的返回值为FilterRegistrationBean的方法来实现JavaBean的注册</p> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 具体实现以下</p> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <span class="confluence-embedded-file-wrapper" style="display:inline-block;"><img class="confluence-embedded-image" src="http://wiki.vipkid.com.cn/download/attachments/8587168/image2017-3-2%2019%3A31%3A31.png?version=1&modificationDate=1488454484000&api=v2" alt="" style="margin:0px 2px;padding:0px;border:0px;display:block;"></span></p> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 须要注意的是此方法须要在被<span style="color:rgb(187,181,41);">@Configuration</span>注解的配置类中</p> <h4 style="margin:20px 0px 0px 30px;padding:0px;color:rgb(51,51,51);font-size:14px;line-height:1.42857;font-family:Arial, sans-serif;"> <span style="color:rgb(0,0,0);">@WebFilter+@ServletComponentScan</span></h4> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <span style="color:rgb(0,0,0);">若是以为Java代码的方式比较繁琐的话能够采用注解方式注册Filter,具体实现方式是在Filter实现类加入@WebFilter注解</span></p> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <span style="color:rgb(0,0,0);">例如</span></p> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <span class="confluence-embedded-file-wrapper" style="display:inline-block;"><img class="confluence-embedded-image" src="http://wiki.vipkid.com.cn/download/attachments/8587168/image2017-3-3%2011%3A36%3A54.png?version=1&modificationDate=1488512224000&api=v2" alt="" style="margin:0px 2px;padding:0px;border:0px;display:block;"></span></p> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 而后在SpringBootApplication类上添加@ServletComponentScan</p> <h3 style="margin:30px 0px 0px;padding:0px;color:rgb(51,51,51);font-size:16px;line-height:1.5;font-family:Arial, sans-serif;"> Filter的注册原理</h3> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 咱们采用JavaConfig的形式实现了Filter的注册,经过向上追溯得知FilterRegistrationBean的层级结构以下</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> ServletContextInitializer</p> <p style="margin-top:10px;margin-bottom:0px;margin-left:30px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> RegistrationBean</p> <p style="margin-top:10px;margin-bottom:0px;margin-left:60px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> AbstractFilterRegistrationBean</p> <p style="margin-top:10px;margin-bottom:0px;margin-left:90px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> FilterRegistrationBean</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 经查阅SpringBoot文档发现针对ServletContextInitializer的描述以下</p> <blockquote style="margin:10px 0px 0px 19px;border-left:1px solid rgb(204,204,204);color:rgb(112,112,112);padding:10px 20px;font-family:Arial, sans-serif;font-size:14px;"> <p style="margin-top:0px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;"> <span style="color:rgb(71,71,71);">Interface used to configure a Servlet 3.0+ </span><a title="class or interface in javax.servlet" href="https://docs.oracle.com/javaee/7/api/javax/servlet/ServletContext.html?is-external=true" class="external-link" style="color:rgb(53,114,176);text-decoration:none;" target="_blank"><code>context</code></a><span style="color:rgb(71,71,71);"> programmatically. Unlike </span><a title="class or interface in org.springframework.web" href="http://docs.spring.io/spring-framework/docs/4.3.6.RELEASE/javadoc-api/org/springframework/web/WebApplicationInitializer.html?is-external=true" class="external-link" style="color:rgb(53,114,176);text-decoration:none;" target="_blank"><code>WebApplicationInitializer</code></a><span style="color:rgb(71,71,71);">, classes that implement this interface (and do not implement </span><a title="class or interface in org.springframework.web" href="http://docs.spring.io/spring-framework/docs/4.3.6.RELEASE/javadoc-api/org/springframework/web/WebApplicationInitializer.html?is-external=true" class="external-link" style="color:rgb(53,114,176);text-decoration:none;" target="_blank"><code>WebApplicationInitializer</code></a><span style="color:rgb(71,71,71);">) will </span><strong>not</strong><span style="color:rgb(71,71,71);"> be detected by </span><a title="class or interface in org.springframework.web" href="http://docs.spring.io/spring-framework/docs/4.3.6.RELEASE/javadoc-api/org/springframework/web/SpringServletContainerInitializer.html?is-external=true" class="external-link" style="color:rgb(53,114,176);text-decoration:none;" target="_blank"><code>SpringServletContainerInitializer</code></a><span style="color:rgb(71,71,71);"> and hence will not be automatically bootstrapped by the Servlet container.</span></p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;"> This interface is primarily designed to allow <a title="interface in org.springframework.boot.web.servlet" href="http://docs.spring.io/spring-boot/docs/1.5.1.RELEASE/api/org/springframework/boot/web/servlet/ServletContextInitializer.html" class="external-link" style="color:rgb(53,114,176);text-decoration:none;" target="_blank"><code>ServletContextInitializer</code></a>s to be managed by Spring and not the Servlet container.</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;"> For configuration examples see <a title="class or interface in org.springframework.web" href="http://docs.spring.io/spring-framework/docs/4.3.6.RELEASE/javadoc-api/org/springframework/web/WebApplicationInitializer.html?is-external=true" class="external-link" style="color:rgb(53,114,176);text-decoration:none;" target="_blank"><code>WebApplicationInitializer</code></a>.</p> </blockquote> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 既然是由SpringBoot进行管理而不是由Servlet容器管理,那么基本能够肯定是由SpringBoot进行管理</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 在org.springframework.boot.context.embedded.tomcat包中咱们找到了答案</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> TomcatEmbeddedServletContainerFactory的一直向上继承了AbstractConfigurableEmbeddedServletContainer</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 而且维护了一个私有的List<ServletContextInitializer>变量,咱们不难猜出,正是由于FilterRegistrationBean继承了ServletContextInitializer而实现了Filter的注册</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 为了进一步验证咱们的猜想,在注册Filter的JavaConfig代码中打了断点跟踪一下</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <span class="confluence-embedded-file-wrapper confluence-embedded-manual-size" style="display:inline-block;"><img class="confluence-embedded-image" height="400" src="http://wiki.vipkid.com.cn/download/attachments/8587168/image2017-3-3%2014%3A32%3A23.png?version=1&modificationDate=1488522753000&api=v2" alt="" style="margin:0px 2px;padding:0px;border:0px;display:block;"></span></p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 能够看到在启动过程当中会获取类型为ServletContextInitializer的Bean</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 继续向下看在SpringBoot内嵌的Tomcat中的TomcatStarter类中也一样实现了ServletContextInitializer</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <span class="confluence-embedded-file-wrapper confluence-embedded-manual-size" style="display:inline-block;"><img class="confluence-embedded-image" height="250" src="http://wiki.vipkid.com.cn/download/attachments/8587168/QQ%E6%88%AA%E5%9B%BE20170303144047.png?version=2&modificationDate=1488523512000&api=v2" alt="" style="margin:0px 2px;padding:0px;border:0px;display:block;"></span><br></p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> </p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 而且在实现方法中执行了AbstractFilterRegistrationBean实现的onStartup方法</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <span class="confluence-embedded-file-wrapper confluence-embedded-manual-size" style="display:inline-block;"><img class="confluence-embedded-image" height="250" src="http://wiki.vipkid.com.cn/download/attachments/8587168/QQ%E6%88%AA%E5%9B%BE20170303144047.png?version=2&modificationDate=1488523512000&api=v2" alt="" style="margin:0px 2px;padding:0px;border:0px;display:block;"></span></p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> 至此Filter注册成功</p> <h1 style="margin:30px 0px 0px;padding:0px;color:rgb(51,51,51);font-size:24px;font-weight:normal;line-height:1.25;border-bottom-color:rgb(204,204,204);font-family:Arial, sans-serif;"> Servlet和Listener</h1> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> Servlet与Listener的支持与Filter大同小异,一样也是支持两种方法进行注册</p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <span style="color:rgb(85,85,85);">JavaConfig的话不一样的是Servlet须要的是ServletRegistrationBean,而Listener须要的是ServletListenerRegistrationBean</span></p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <span style="color:rgb(85,85,85);">注解的话则分别是经过@WebServlet、@WebListener进行注解</span></p> <p style="margin-top:10px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;color:rgb(51,51,51);font-family:Arial, sans-serif;font-size:14px;"> <span style="color:rgb(85,85,85);">至于注册管理过程则基本与Filter相同</span></p> </div>java