一次踩坑后的记录及总结~
上一次自定义添加RequestWrapper的filter在@Component时明明没有定义@Order,并且公共包里添加ContentCachingRequestWrapper的filter的@Order明明是有值的,按照一般的逻辑来说指定顺序的优先执行,没有指定顺序的后执行,但是结果却不是这样的,自定义的filter比公共包里的filter先执行了。
下图公共包的filter
下图自定义的filter
但是添加到链中反而不是这样的顺序。
而再自定义filter上加了@Order顺序也没有改变,依旧是公共包的filter在前
打了个断点跟踪了下添加filter的地方,这里看源码ServletContextInitializerBeans的方法addAdapteableBeans,红色框中是从容器中添加filter
getOrderedBeanOfType里面从容器中获取beans
再看getOrderedBeansOfType方法,先从容器中beanDefinitionNames是有序的(添加顺序),然后按照顺序getBean创建bean,最后通过AnnotationAwareOrderComparator排序。
看下AnnotationAwareOrderComparator这个类,从名字上看是有注解意识的Order比较器,是支持注解排序的,看下里面比较逻辑:哪个实现了PriorityOrdered接口,哪个优先。
先通过RootBeanDefinition找顺序,没有再通过当前对象找
下面,这个地方是从类上搜索有没有@Order注解和@Priority注解
从源码中并没有发现跟@Configuration中方法@Order相关的处理,而正好也是目前在@Configuration中使用@Order指定顺序失效的一个证据。
结论 :
1.在@Configuration里面通过@Bean是方式创建bean,在上面加@Order控制顺序是没有效果的
2. 控制顺序方式:
- 实现Ordered接口
- 实现PriorityOrdered接口
- 在类上面加@Order
- 在类上面加@Priority
- 可以通过RegistrationBean方式创建bean,用setOrder添加顺序
- filter可以通过FilterRegistrationBean创建filter的bean,指定顺序