在SpringBoot工程中使用filter进行过滤需要进行的步骤
- 自定义一个Filter类,实现Filter接口
- 在FilterConfiguration类(加了@Configuration的注解)中注册Filter,加上@Bean注解并在FilterRegistrationBean中设置Filter的优先级
- Filter接口中有三个方法,doFilter()是真正实现过滤的地方;其中方法参数之一的filterChain是工程Filter的一个执行链路代理,在进行过滤操作之后执行的filterChain.doFilter()方法会把request请求发往后续的Filter或者是servlet。
注:Filter可以实现的功能部分也可由Interceptor来实现
Filter能够顺序执行就是因为FilterChain的存在,每一个filter执行filterChain.doFilter()的时候都会把filterChain对象传入,然后交给下一个filter,目的就是保证每一个filter都可以持有filterChain,直到把所有的filter都执行完。在执行完servlet之后还会倒序返回到各个filter中。Filter的生命周期没有特别声明时同servlet一样。
FilterChain源码链路分析
首先debug查看工程的chain,包含的有
YouCan-filter
->httpmonitor-filter
->SetCharacterEncoding
->YouCanCommonFilter
->YouCanApp-filter
->log4j2-filter
->rhinoControl-filter
->set-proxy-filter
->applicationContextIdFilter
->Jetty_WebSocketUpgradeFilter
->dispatcherServlet@7ef5559e==org.springframework.web.servlet.DispatcherServlet,jsp=null,order=-1,inst=true
工程使用的是jetty容器,分析一下jetty中对于Filter的执行处理,
首先是javax.servlet-api中的Filter接口和FilterChain接口
public interface Filter {
public void init(FilterConfig filterConfig) throws ServletException;
/**
* 1.doFilter中都是使用chain.doFilter把执行流交给FilterChain来管理;doFilter之前的部分都是处理之前的过滤操作,之后的部分都是处理之后的过滤操作
* 2.自定义Filter中重点关注的部分就是doFilter方法,关乎了过滤的意义
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException;
public void destroy();
}
public interface FilterChain {
public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException;
}
接着是Jetty中的CacheChain,springBoot使用了jetty容器(默认tomcat),因此FilterChain是由它来实现的
protected class CachedChain implements FilterChain {
// 当前filter的持有者
FilterHolder _filterHolder;
// 指向下一个filter,没有则为null
ServletHandler.CachedChain _next;
// servlet处理的持有者
ServletHolder _servletHolder