@ExceptionHandler处理全局异常的优先级说明

1. 前言

  1. 在工作中,遇到使用@RestControllerAdvice与@ExceptionHandler注解进行全局异常错误处理(之前写过文章)。
  2. 在上述文章中,讲到优先级部分只是粗略提及到:即设置了全局异常处理方法,又设置了controller层异常处理的方法,优先选择自己的controller层
  3. 而在这次工作中,遇到了:在不同包下都设置了全局异常处理方法,而并不是按照错误类型越精确就使用谁的方法进行处理,因此,特意研究一下,并记录下来。

2. 先说结论

  1. 一个项目下,存在分布于不同包不同类中的被@ExceptionHandler注解的方法(全局异常处理方法),优先级:
    1. 优先看包顺序,包在前面的异常处理方法,优先级更高。
    2. 在同包下,类在前面的异常处理方法,优先级更高。
    3. 在同类下,则是看精确度,越精确的错误类型,优先级越高。

3. 证明结论

1. 在同类下,越精确的错误类型,优先级越高

  1. 在同类下,无需在意该类下的被@ExceptionHandler注解的方法的先后顺序,此时匹配的是错误类型的精确度,越精确的错误类型,优先级越高。

  2. 代码如下

    // 全局异常处理
    // Exception 包括IndexOutOfBoundsException、NullPointerException
    // IndexOutOfBoundsException与NullPointerException 无关系
    @RestControllerAdvice
    public class ExceptionAHandleOne {
    
        @ExceptionHandler(value = Exception.class)
        public void handleException(Exception e){
            System.out.println("我是ExceptionHandleAOne中Exception处理:" + e.getMessage());
        }
    
        @ExceptionHandler(value = IndexOutOfBoundsException.class)
        public void handleIndexOutOfBoundsException(IndexOutOfBoundsException e){
            System.out.println("我是ExceptionHandleAOne中IndexOutOfBoundsException处理:" + e.getMessage());
        }
    
        @ExceptionHandler(value = NullPointerException.class)
        public void handleNullPointerException(NullPointerException e){
            System.out.println("我是ExceptionHandleAOne中NullPointerException处理:" + e.getMessage());
        }
        
    }
    
    @RestController
    public class ExceptionTestController {
    
        @GetMapping("/test")
        public void test(){
            System.out.println("下标越界异常");
            throw new IndexOutOfBoundsException("下标越界异常");
        }
    
        @GetMapping("/test2")
        public void test2(){
            System.out.println("空指针异常");
            throw new NullPointerException("空指针异常");
        }
    
        @GetMapping("/test3")
        public void test3(){
            System.out.println("运行时异常");
            throw new RuntimeException("运行时异常");
        }
    }
    

    在这里插入图片描述

2. 在同包下,类在前面的异常处理方法,优先级更高

  1. 解释:在同包下,类A 中方法被@ExceptionHandler(value = Exception.class) ,类B中方法 被 @ExceptionHandler(value = IndexOutOfBoundsException.class),此时报错是IndexOutOfBoundsException,但进入的方法是类A中的。

  2. 代码如下:
    在这里插入图片描述

    @RestControllerAdvice
    public class ExceptionAHandleOne {
    
        @ExceptionHandler(value = Exception.class)
        public void handleException(Exception e){
            System.out.println("我是ExceptionHandleAOne中Exception处理:" + e.getMessage());
        }
    
        @ExceptionHandler(value = NullPointerException.class)
        public void handleNullPointerException(NullPointerException e){
            System.out.println("我是ExceptionHandleAOne中NullPointerException处理:" + e.getMessage());
        }
    
    }
    
    @RestControllerAdvice
    public class ExceptionAHandleTwo {
    
        @ExceptionHandler(value = IndexOutOfBoundsException.class)
        public void handleIndexOutOfBoundsException(IndexOutOfBoundsException e){
            System.out.println("我是ExceptionHandleATwo中IndexOutOfBoundsException处理:" + e.getMessage());
        }
    
    }
    

    在这里插入图片描述
    在这里插入图片描述

3. 优先看包顺序,包在前面的异常处理方法,优先级更高。

  1. 在项目中,包A中类的方法处理被@ExceptionHandler(value = Exception.class) ,包B中的类方法 被 @ExceptionHandler(value = IndexOutOfBoundsException.class),此时报错是IndexOutOfBoundsException,但进入的方法是包A中的类

  2. 代码如下:
    在这里插入图片描述

    @RestControllerAdvice
    public class ExceptionAHandleOne {
    
        @ExceptionHandler(value = Exception.class)
        public void handleException(Exception e){
            System.out.println("我是ExceptionHandleAOne中Exception处理:" + e.getMessage());
        }
    
        @ExceptionHandler(value = NullPointerException.class)
        public void handleNullPointerException(NullPointerException e){
            System.out.println("我是ExceptionHandleAOne中NullPointerException处理:" + e.getMessage());
        }
    
    }
    
    @RestControllerAdvice
    public class ExceptionBHandleOne {
    
        @ExceptionHandler(value = IndexOutOfBoundsException.class)
        public void handleIndexOutOfBoundsException(IndexOutOfBoundsException e){
            System.out.println("我是ExceptionBHandleOne中IndexOutOfBoundsException处理:" + e.getMessage());
        }
    
    }
    

    在这里插入图片描述
    在这里插入图片描述

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
@ControllerAdvice 是一个注解,用于定义全局异常处理器类。我们可以在该类中定义多个 @ExceptionHandler 注解方法来处理不同类型的异常。当系统中出现异常时,会根据异常类型找到对应的 @ExceptionHandler 方法进行处理。 具体的步骤如下: 1. 创建一个类,并用 @ControllerAdvice 注解标记。 2. 在该类中定义多个方法,每个方法上使用 @ExceptionHandler 注解,并传入对应的异常类型作为参数。 3. 在方法中编写具体的异常处理逻辑。 例如,我们可以创建一个全局异常处理器类 GlobalExceptionHandler: ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<String> handleException(Exception e) { // 处理 Exception 类型的异常 // 返回自定义的错误信息 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal Server Error"); } @ExceptionHandler(RuntimeException.class) public ResponseEntity<String> handleRuntimeException(RuntimeException e) { // 处理 RuntimeException 类型的异常 // 返回自定义的错误信息 return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Bad Request"); } // 可以添加更多的异常处理方法... } ``` 在上述例子中,我们定义了两个异常处理方法,分别处理 Exception 类型和 RuntimeException 类型的异常。当系统中抛出对应的异常时,会调用相应的处理方法并返回自定义的错误信息。 这样,在整个系统中任何地方出现的对应类型的异常都会被统一处理,提高了代码的可维护性和错误处理的一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值