1 @WebFilter过滤器使用@Order无效
启动程序:
Controller:
实现俩过滤器:
- AuthFilter
- TimeCostFilter
使用 @Order,期望 TimeCostFilter 先被执行,因为TimeCostFilter原本设计是统计这个接口性能,所以需要统计AuthFilter执行的授权过程。
全部代码实现完毕,执行结果如下:
观察日志,执行时间并不包含授权过程,所以这违背预期,明明加了 @Order呀!
但若交换Order指定的值,发现也没效果,why?Order不能排序WebFilter?
源码解析
当请求来时,会执行到 StandardWrapperValve#invoke(),创建 ApplicationFilterChain,并通过ApplicationFilterChain#doFilter() 触发过滤器执行,并最终执行到内部私有方法internalDoFilter(),尝试在internalDoFilter()中寻找一些启示:
可知,过滤器执行顺序由实例变量Filters维护,Filters是createFilterChain()在容器启动时顺序遍历StandardContext中的成员变量FilterMaps所获:
发现对 StandardContext#FilterMaps 的写入是在
addFilterMapBefore()
过滤器的执行顺序由StandardContext#FilterMaps顺序决定,而FilterMaps则是一个包装过的数组,所以只要进一步弄清FilterMaps中各元素的排列顺序即可。
addFilterMapBefore()中加入断点:
Spring从selfInitialize()一直调用到addFilterMapBefore()。
selfInitialize()通过调用
getServletContextInitializerBeans()获取所有ServletContextInitializer类型Bean,并调用该Bean的onStartup(),最终调用到addFilterMapBefore()。
上述的selfInitialize()又从何处调用过来呢?
selfInitialize()
getServletContextInit