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

文章目录

  • 1. 前言
  • 2. 先说结论
  • 3. 证明结论
    • 1. 在同类下,越精确的错误类型,优先级越高
    • 2. 在同包下,类在前面的异常处理方法,优先级更高
    • 3. 优先看包顺序,包在前面的异常处理方法,优先级更高。

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("运行时异常");
        }
    }
    

    @ExceptionHandler处理全局异常的优先级说明_第1张图片

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

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

  2. 代码如下:
    @ExceptionHandler处理全局异常的优先级说明_第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());
        }
    
    }
    

    @ExceptionHandler处理全局异常的优先级说明_第3张图片
    @ExceptionHandler处理全局异常的优先级说明_第4张图片

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

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

  2. 代码如下:
    @ExceptionHandler处理全局异常的优先级说明_第5张图片

    @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());
        }
    
    }
    

    @ExceptionHandler处理全局异常的优先级说明_第6张图片
    @ExceptionHandler处理全局异常的优先级说明_第7张图片

你可能感兴趣的:(小知识,java,spring,Exception)