java全局异常处理器能捕获自定义异常,前提是异常继承runtimeexception、@controlleradvice被spring扫描到、@exceptionhandler方法规范且异常在controller层抛出。

Java 全局异常处理器能捕获自定义异常,但前提是它被 Spring 正确识别、注册,并且异常抛出路径符合 MVC 拦截规则。常见“捕获不到”的问题,基本不是代码逻辑错,而是配置或使用细节不到位。
确保自定义异常类设计合理
自定义异常应继承 RuntimeException(非受检异常),这是 REST 接口场景下的推荐做法:
- 避免强制 try-catch,让业务层专注逻辑,异常统一交由全局处理器处理
- 若继承 Exception(受检异常),需显式 throws 或 try-catch,否则编译不通过,反而破坏全局拦截链路
- 建议携带 code 和 message 字段,便于前端识别和日志追踪
示例:
public class BusinessException extends RuntimeException {<br> private final int code;<br> private final String message;<br><br> public BusinessException(int code, String message) {<br> super(message);<br> this.code = code;<br> this.message = message;<br> }<br><br> // getter 方法略
@ControllerAdvice 类必须被 Spring 扫描到
Spring Boot 默认只扫描启动类所在包及其子包。如果你的异常处理器放在 com.example.exception,而启动类在 com.example.web,那它根本不会被加载。
- 最稳妥方式:把
@ControllerAdvice类放到启动类同包或子包下,例如com.example.web.advice.GlobalExceptionHandler - 次选方式:在
@SpringBootApplication上显式声明扫描路径:@ComponentScan(basePackages = {"com.example.web", "com.example.exception"})
@ExceptionHandler 方法写法要规范
方法签名看似简单,但几个关键点容易出错:
- 不能是 static 方法——Spring 依赖反射调用实例方法,static 会被完全忽略
- 参数只能是异常类型或其父类,支持额外注入
HttpServletRequest、HttpServletResponse等上下文对象 - 返回值建议用
@ResponseBody+ 自定义响应体(如Result>),或直接用ResponseEntity>
正确示例:
@ExceptionHandler(BusinessException.class)<br>public ResponseEntity<result>> handleBusinessException(BusinessException e) {<br> Result> result = Result.fail(e.getCode(), e.getMessage());<br> return ResponseEntity.status(HttpStatus.OK).body(result);<br>}</result>
确认异常是在 Controller 层抛出的
@ControllerAdvice 只能捕获进入 DispatcherServlet 后、Controller 方法执行过程中抛出的异常:
- Service 层抛出的异常,只要没被中间层(如 AOP、Filter)提前吞掉,最终会冒泡到 Controller,就能被捕获
- Filter、Interceptor 中抛出的异常,或 Controller 外部(如定时任务、异步线程)抛出的异常,不会进入 @ControllerAdvice
- 若用了 @Async,需配合
@AsyncUncaughtExceptionHandler单独处理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











