统一异常处理
统一的异常处理方式,就是定义 ExceptionHandler。具体来说,就是使用 @ControllerAdvice 和 @ExceptionHandler 两个注解。
这种异常处理下,会给所有或者指定的 Controller 织入异常处理的逻辑(AOP)。当 Controller 方法抛出异常后,由被 @ExceptionHandler 修饰的方法进行处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @ControllerAdvice @ResponseBody public class GlobalExceptionHandler {
@ExceptionHandler(BaseException.class) public ResponseEntity<?> handleAppException(BaseException ex, HttpServletRequest request) { }
@ExceptionHandler(value = ResourceNotFoundException.class) public ResponseEntity<ErrorReponse> handleResourceNotFoundException(ResourceNotFoundException ex, HttpServletRequest request) { } }
|
原理
ExceptionHandlerMethodResolver 中 getMappedMethod 方法决定了异常具体被哪个被 @ExceptionHandler 注解修饰的方法处理异常。
具体来说,就是首先找到可以匹配处理异常的所有方法信息,然后对其进行从小到大的排序,最后取最小的那一个匹配的方法(匹配程度最高的那一个)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Nullable private Method getMappedMethod(Class<? extends Throwable> exceptionType) { List<Class<? extends Throwable>> matches = new ArrayList<>(); for (Class<? extends Throwable> mappedException : this.mappedMethods.keySet()) { if (mappedException.isAssignableFrom(exceptionType)) { matches.add(mappedException); } } if (!matches.isEmpty()) { matches.sort(new ExceptionDepthComparator(exceptionType)); return this.mappedMethods.get(matches.get(0)); } else { return null; } }
|