springboot使⽤多个@RestControllerAdvice时的拦截顺序
修改⽇志:
springboot aop 2021-08-27 补充源码说明,增加@Order、@Priority、@Primary 三个注解和 Ordered 接⼝说明
我们的项⽬中经常会使⽤到别⼈的模块,例如我的项⽬demo,要依赖别⼈的A模块,以及基础的核⼼core模块,此时core模块有⼀个使⽤了@RestControllerAdvice的类,负责拦截所有的controller异常。
但是呢,他的异常处理不符合我们demo项⽬的要求,这就导致我们demo项⽬要重写⾃⼰的controller异常拦截。
此时我们可以⽤的解决异常的⽅法有三种:
1、使⽤aop进⾏切⾯拦截异常
2、controller每个⽅法都⽤try-catch捕获异常
3、增加⼀个@RestControllerAdvice标注的类,负责处理我们项⽬的controller异常。
我选⽤第三种⽅法,但是当我写了个PartControllerAdvice类,指定basePackages为我⾃⼰的项⽬包,
依旧还是被core模块的全局异常处理类拦截了。
查资料和博客发现如果有多个加了@RestControllerAdvice的类,他们会依次加载,遇到异常时,按照类加载顺序进⾏判断,如果前⾯的类有能处理这个异常的⽅法,就给前⾯的类处理。
我的项⽬中有两个标注了@RestControllerAdvice的类,core模块的类被先加载,且core模块的异常处理类有个⽅法专门处理Exception类型的异常,所以我的局部异常处理类始终不执⾏。
解决⽅法:
@Order(Ordered.HIGHEST_PRECEDENCE) 使⽤@Order注解,提⾼⾃⼰的局部异常处理类的加载顺序就⾏了
代码:
模拟效果:
源码说明:
@Order、@Priority、@Primary 三个注解和 Orderd 接⼝说明
orderd接⼝,实现Oderd接⼝的话要实现int getOrder();这个⽅法,返回⼀个整数值,值越⼩优先级越⾼。
@Order⾥⾯存储了⼀个值,默认为Integer的最⼤值,同样值越⼩优先级越⾼。要注意@Order只能控制组件的加载顺序,不能控制注⼊的优先级。但是能控制List ⾥⾯存放的XXX的顺序,原因是当通过构造函数或者⽅法参数注⼊进某个List时,Spring的
DefaultListableBeanFactory类会在注⼊时调⽤AnnotationAwareOrderComparator.sort(listA)帮我们去完成根据@Order或者Ordered接⼝序值排序。@Order更加适⽤于集合注⼊的排序。
@Priority与@Order类似,@Order是Spring提供的注解,@Priority是JSR 250标准,同样是值越⼩优先级越⾼。但是两者还是有⼀定却别,@Priority能够控制组件的加载顺序,因此@Priority侧重于单个注⼊的优先级排序。此外@Priority优先级⽐@Order更⾼,两者共存时优先加载@Priority。
@Primary是优先级最⾼的,如果同时有@Primary以及其他⼏个的话,@Primary注解的Bean会优先加载。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论