-
如果项目中Controller继承某个带有@ExceptionHandler注解方法的类,那么Controller抛出异常时,会优先走该@ExceptionHandler注解的方法。
-
此时如果有另外带有@RestControllerAdvice注解的全局异常处理器,其只处理Controller继承的@ExceptionHandler范围外的异常。
-
如果@ExceptionHandler范围很大,比如是Throwable.class,那么所有异常只走Controller继承的异常处理方法,不会经过全局异常处理器。
(ps:@ExceptionHandler存在多个时,最具体的一个生效,比如Throwable.class和RuntimeException.class,如果抛出后者,则拦截后者的方法生效)
// 举例子(下面共1. 2. 3. 三个类):
/*
情况一:TestController抛出 ArrayStoreException,那么被ExceptionHandlers处理(如果ExceptinonHandlers再上抛,就直接服务停止了,而不是被ExceptionHandlers处理)
情况二:TestController抛出 ArrayStoreException以外的异常(超出AbstractController拦截的范围),那么被ExceptionHandlers处理(同样如果再上抛,直接服务停止)
情况三:假设AbstractController中的handleThrowable上的@ExceptionHandler(ArrayStoreException.class)改成@ExceptionHandler(Throwable.class),那么所有异常只被AbstractController处理,全局异常处理器无作为(当然如果其他Controller没有继承AbstractController的话,就会抛异常被全局异常处理器ExceptionHandlers处理)。
*/
// 1. 带有@ExceptionHandler注解方法的 AbstractController
public abstract class AbstractController {
@ExceptionHandler(ArrayStoreException.class)
public Object handleThrowable(HttpServletRequest request, Throwable e) {}
}
// 2. 全局异常处理器
@RestControllerAdvice
public class ExceptionHandlers {
@ExceptionHandler(Throwable.class)
public String handleThrowable(HttpServletRequest request, Throwable e) {}
}
// 3. 普通Controller
@RestController
@RequestMapping("/test")
public class TestController extends AbstractController {
@GetMapping("/test001")
public String test001() throws Throwable {}
}