1. 前言
- 在工作中,遇到使用@RestControllerAdvice与@ExceptionHandler注解进行全局异常错误处理(之前写过文章)。
- 在上述文章中,讲到优先级部分只是粗略提及到:即设置了全局异常处理方法,又设置了controller层异常处理的方法,优先选择自己的controller层。
- 而在这次工作中,遇到了:在不同包下都设置了全局异常处理的方法,而并不是按照错误类型越精确就使用谁的方法进行处理,因此,特意研究一下,并记录下来。
2. 先说结论
- 一个项目下,存在分布于不同包下不同类中的被@ExceptionHandler注解的方法(全局异常处理方法),优先级:
- 优先看包顺序,包在前面的异常处理方法,优先级更高。
- 在同包下,类在前面的异常处理方法,优先级更高。
- 在同类下,则是看精确度,越精确的错误类型,优先级越高。
3. 证明结论
1. 在同类下,越精确的错误类型,优先级越高
-
在同类下,无需在意该类下的被@ExceptionHandler注解的方法的先后顺序,此时匹配的是错误类型的精确度,越精确的错误类型,优先级越高。
-
代码如下:
// 全局异常处理 // 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. 在同包下,类在前面的异常处理方法,优先级更高
-
解释:在同包下,类A 中方法被
@ExceptionHandler(value = Exception.class)
,类B中方法 被@ExceptionHandler(value = IndexOutOfBoundsException.class)
,此时报错是IndexOutOfBoundsException,但进入的方法是类A中的。 -
代码如下:
@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. 优先看包顺序,包在前面的异常处理方法,优先级更高。
-
在项目中,包A中类的方法处理被
@ExceptionHandler(value = Exception.class)
,包B中的类方法 被@ExceptionHandler(value = IndexOutOfBoundsException.class)
,此时报错是IndexOutOfBoundsException,但进入的方法是包A中的类。 -
代码如下:
@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()); } }