Spring全局异常处理RestControllerAdvice优先级问题

多个RestControllerAdvice

存在多个@RestControllerAdvice,且未使用@Order注解声明使用顺序时,实际运行会有Advice乱序的问题(就是同一个异常在不同机器上使用的Advice可能是不一样的)。为避免此乱序问题应使用@Order来指定优先级(也可把controller和advice分成多组,同组的放到同一个包下,不同组的反之)

举例
同时存在AaaHandlerAdvice、BbbHandlerAdvice 且包名都是【com.test.controller】
而ConfigController的包名也是【com.test.controller】或它的子包,这时候Advice会有乱序的问题,同一个异常在不同机器上使用的Advice可能是不一样的,如此响应status code有两种可能:
【AaaHandlerAdvice】时:200
【BbbHandlerAdvice】时:500

@RestControllerAdvice(basePackageClasses = {ConfigController.class})
public class AaaHandlerAdvice {

    @ExceptionHandler(value = {Exception.class})
    @ResponseStatus(HttpStatus.OK)
    public Result handler(Exception ex) {
        return Result.fail(ex);
    }
}
@RestControllerAdvice(basePackages = {"com.test.controller"})
public class BbbHandlerAdvice {

    @ExceptionHandler(value = {Exception.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result handler(Exception ex) {
        return Result.fail(ex);
    }
}

另需注意:
@RestControllerAdvice的属性basePackageClasses也是扫包的(包含子包),等价于basePackage。而非惯性思维的仅处理类自身的异常。

ArgumentResolver 是 Spring MVC 中用于参数绑定的关键组件之一,其初始化过程如下: 1. Spring MVC 在启动时会扫描所有的 bean,通过 @ControllerAdvice、@RestControllerAdvice 等注解找到所有的全局异常处理器和全局数据绑定器; 2. 在扫描过程中,Spring MVC 会找到所有实现了 HandlerMethodArgumentResolver 接口的 bean,并将其加入到 ArgumentResolver 集合中; 3. 当请求到达 DispatcherServlet 后,Spring MVC 会根据请求 URL 找到对应的 HandlerMapping,并调用其 getHandler 方法获取 HandlerExecutionChain 对象; 4. HandlerExecutionChain 对象包含了请求对应的 Controller 方法以及其参数列表,Spring MVC 会遍历参数列表中的每个参数并根据类型查找对应的 ArgumentResolver; 5. 找到合适的 ArgumentResolver 后,Spring MVC 会调用其 supportsParameter 方法判断当前参数是否支持绑定; 6. 如果支持绑定,则调用其 resolveArgument 方法进行参数绑定; 7. 如果未找到合适的 ArgumentResolver,则抛出异常或返回 null。 在 ArgumentResolver 初始化过程中,最重要的是找到合适的 ArgumentResolver,这需要根据参数类型以及其他条件进行匹配。如果系统中有多个 ArgumentResolver 都支持绑定同一种类型的参数,那么 Spring MVC 会根据优先级顺序选择其中一个进行绑定。如果所有的 ArgumentResolver 都无法进行绑定,则抛出异常或返回 null。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值