1. 为什么要用它?(安全网类比)
想象一下,你开了一家大型商场(你的 JavaWeb 系统):
- 没处理器时:每个收银台(Controller)都得自己准备灭火器、急救包。万一有个收银台突然起火(代码出 Bug,比如
1/0),收银员直接懵了,顾客看到的是满屋烟雾(一堆看不懂的报错代码)。 - 有处理器后:你在商场顶层设了一个“应急中心”。不管哪个柜台出事,消息都会汇总到这儿。应急中心会统一给顾客发个短信:“抱歉,系统维护中,请稍后再试”。
一句话总结:它就是一个“兜底”的,专门负责把程序里各种乱七八糟的报错,转换成用户能看懂的人话。
2. 它是怎么工作的?
你会创建一个异常处理类。这个类有两件“法宝”:
第一件:@RestControllerAdvice
- 大白话:这是一个“全局监控摄像头”。
- 作用:它告诉 Spring:“盯着点儿所有的 Controller,谁那里要是出事了(抛异常了),立刻把锅甩给我来处理!”
第二件:@ExceptionHandler
-
大白话:这是“专项小组”。
-
用法:你可以在方法上指定它处理哪种异常。
- 比如专门处理
ArithmeticException(数学运算异常,像那个1/0)。 - 或者直接处理
Exception.class(所有异常都管)。
- 比如专门处理
3. 代码长什么样?
Java
@RestControllerAdvice // 开启全局捕获
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class) // 只要出异常,就跑这个方法
public Result handleException(Exception ex) {
ex.printStackTrace(); // 在后台偷偷打印日志,方便程序员找 Bug
// 给前端返回一个统一的、体面的格式
return Result.error("对不起,系统接口异常,请联系管理员!");
}
}
4. 为什么要配合“事务”使用?
这跟事务也很有关系:
- 如果在 Service 层发生了异常(比如保存员工时出错了),如果不处理,异常会一直向上抛。
- 全局异常处理器会“接住”这个异常。
- 关键点:正因为异常被抛出了,Spring 的事务管理器(
@Transactional)才能感知到“出事了”,从而触发回滚,保证数据不乱。
总结
| 对比项 | 以前(不推荐) | 现在(全局异常处理器) |
|---|---|---|
| 代码量 | 每个 Controller 都要写大量的 try-catch | 只写一个类,全系统通用 |
| 用户体验 | 看到 500 错误页面或长串代码 | 看到统一的“系统异常”提示 |
| 维护性 | 极差,改一处得改一百处 | 极好,只需改这一个类 |