Spring Boot 在处理异常时,会从上到下查找最具体的 @ExceptionHandler
方法:
先看是否有匹配的异常处理方法(
CustomException.class
)。如果找到,就调用对应的方法,不再继续查找。
如果找不到,就会向上寻找更通用的异常处理方法(比如
Exception.class
)。
你的代码执行逻辑
如果你抛出了 CustomException
:
Spring 发现
@ExceptionHandler(CustomException.class)
正好匹配CustomException
,只会执行这个方法。@ExceptionHandler(Exception.class)
是兜底的(更泛型的异常处理),不会执行。
如果你抛出的是 NullPointerException
或 RuntimeException
:
Spring 找不到
@ExceptionHandler(NullPointerException.class)
,会走@ExceptionHandler(Exception.class)
这个兜底方法。
验证代码
你可以在 CustomException
处理方法和 Exception
处理方法里分别加上不同的日志:
@ExceptionHandler(CustomException.class)
@ResponseBody
public ResponseResult exception(CustomException e){
log.warn("Handled by CustomException handler: {}", e.getMessage());
return ResponseResult.errorResult(e.getAppHttpCodeEnum());
}
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult exception(Exception e){
log.error("Handled by Exception handler: {}", e.getMessage());
return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
}
然后在代码里抛出 CustomException
:
throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
你会发现日志只会打印 Handled by CustomException handler: xxx
,而 Exception
处理方法不会触发。
总结
✅ CustomException
只会被 @ExceptionHandler(CustomException.class)
处理。
✅ Exception.class
处理方法只是兜底,不会拦截 CustomException
。
✅ Spring 只会执行一个最匹配的 @ExceptionHandler
方法,不会执行多个。