miller
发布于

springboot 使用多个 @RestControllerAdvice 时的拦截顺序

原文地址 www.cnblogs.com

修改日志:

  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 注解,提高自己的局部异常处理类的加载顺序就行了

代码:

 

 

模拟效果:

 

参考文章:https://www.cnblogs.com/code-to-world/p/12779588.html      springboot 多个 @ControllerAdvice 全局异常处理

源码说明:

 

 

@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 会优先加载。

浏览 (346)
点赞
收藏
评论