多个标注相同@Order值的@ControllerAdvice在Spring中的加载规则是什么
同Order值的@ControllerAdvice生效优先级规则
你观察到的应用内ControllerAdvice1优先生效的现象符合Spring的默认加载规则,你的猜测也是正确的:当两个@ControllerAdvice的@Order值完全相同时,生效优先级由Spring容器的Bean注册顺序决定,和包扫描顺序直接相关。
核心规则说明
1. 有序组件排序逻辑
Spring对@ControllerAdvice这类切面组件默认使用AnnotationAwareOrderComparator排序:
- 优先比较
@Order注解或Ordered接口返回的权重值,值越小优先级越高 - 当权重值完全相同时,采用稳定排序逻辑,保留Bean在容器中的注册顺序作为相对优先级,更早注册的组件会被优先匹配到。
2. Bean注册顺序的决定逻辑
Spring Boot的@SpringBootApplication注解默认的包扫描范围是启动类所在的包及其所有子包,这部分路径下的组件会在启动阶段优先被扫描、注册到容器中。
你提供的两个组件代码如下:
应用内的ControllerAdvice:
package com.package.one.errors @ControllerAdvice @Order(Ordered.HIGHEST_PRECEDENCE) public class ControllerAdvice1 {}
依赖包中的ControllerAdvice:
package com.package.two.errors @ControllerAdvice @Order(Ordered.HIGHEST_PRECEDENCE) public class ControllerAdvice2 {}
由于ControllerAdvice1和启动类同属com.package.one父包,会比依赖包中的ControllerAdvice2更早完成注册,因此在Order值相同的情况下优先生效。
3. 优先级调整方案
如果需要让依赖包的ControllerAdvice2优先生效,可采用两种方案:
- 调低应用内
ControllerAdvice1的优先级,例如配置@Order(Ordered.HIGHEST_PRECEDENCE + 10),因为Ordered.HIGHEST_PRECEDENCE是Integer类型最小值,已是理论最高优先级,无法再配置更高的权重值,只能调低另一组件的权重 - 为两个
@ControllerAdvice分别配置basePackages、annotations等属性,缩小各自的作用范围,避免切面生效范围重叠,从根源上解决优先级冲突问题。
内容的提问来源于stack exchange,提问作者EDR
相关产品推荐
相关产品推荐

