它们都用于实现全局的通用处理逻辑,主要应用在以下三个方面:
- 全局异常处理: 使用
@ExceptionHandler注解的方法。 - 全局数据绑定: 使用
@InitBinder注解的方法。 - 全局数据预处理: 使用
@ModelAttribute注解的方法。
联系:
- 核心功能相同: 两者都提供了上述三种全局处理的能力。我们可以将原本分散在多个 Controller 中的通用异常处理、数据绑定规则、公共 Model 属性提取到标有这两个注解的类中统一管理。
- 都是
@Component: 从 Spring 的角度看,它们都是@Component的特殊化注解。这意味着 Spring 容器会自动扫描并注册这些 Bean。 @RestControllerAdvice是@ControllerAdvice的组合注解: 这是最关键的联系。@RestControllerAdvice本质上是@ControllerAdvice和@ResponseBody两个注解的组合。
查看 @RestControllerAdvice 的源码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ControllerAdvice // <--- 包含了 @ControllerAdvice
@ResponseBody // <--- 包含了 @ResponseBody
public @interface RestControllerAdvice {
// ... 注解属性定义 ...
}
区别 (核心在于 @ResponseBody):
这个组合带来的核心区别在于对包含 @ExceptionHandler 注解的方法的返回值处理方式不同:
-
@ControllerAdvice:- 如果其内部的
@ExceptionHandler方法没有添加@ResponseBody注解,那么其返回值通常会被视图解析器(ViewResolver)处理。会返回一个String类型的视图名,或者一个ModelAndView对象,用于页面跳转或渲染。 - 如果其内部的
@ExceptionHandler方法添加了@ResponseBody注解,就和@RestControllerAdvice中的方法一样了,返回值会直接写入 HTTP 响应体中,通常是 JSON 或 XML 格式。
- 如果其内部的
-
@RestControllerAdvice:- 由于它自带了
@ResponseBody注解,所以其内部所有@ExceptionHandler方法(以及@ModelAttribute方法)的返回值默认就会被 Spring MVC 当作响应体内容处理,通过HttpMessageConverter进行序列化(例如转为 JSON)并写入 Response Body。 - 它特别适用于构建 RESTful API 的全局异常处理,因为 REST API 通常期望返回的是数据(如 JSON),而不是一个 HTML 视图。
- 由于它自带了
总结与选择:
| 特性 | @ControllerAdvice |
@RestControllerAdvice (@ControllerAdvice + @ResponseBody) |
|---|---|---|
| 核心目的 | 全局 Controller 增强 (异常、数据绑定、模型属性) | 全局 Controller 增强 (异常、数据绑定、模型属性) |
| 基础注解 | @Component |
@Component |
| 组合 | 无 | @ControllerAdvice + @ResponseBody |
@ExceptionHandler 返回值默认处理 |
视图解析 (返回视图名/ModelAndView) | 写入响应体 (通过 HttpMessageConverter 转为 JSON/XML 等) |
| 适用场景 | 1. 传统的 Spring MVC 应用 (返回 HTML 视图) 2. 需要混合处理(部分返回视图,部分加 @ResponseBody 返回 JSON)的应用3. 只用于全局 @InitBinder 或不返回数据的 @ModelAttribute |
1. RESTful API (主要返回 JSON/XML 数据) 2. 所有全局异常都希望返回 JSON/XML 错误结构体 |
简单来说:
- 如果你在构建一个传统的、主要返回 HTML 页面的 Spring MVC 应用,或者需要灵活处理部分返回视图、部分返回 JSON 的情况,使用
@ControllerAdvice。如果某个异常处理器需要返回 JSON,可以在该方法上单独加@ResponseBody。 - 如果你在构建一个纯粹的 RESTful API,所有的 Controller 和异常处理都期望返回 JSON 或 XML 数据,那么使用
@RestControllerAdvice更方便,因为它省去了在每个@ExceptionHandler方法上都写@ResponseBody的麻烦。
示例:
使用 @ControllerAdvice (可能返回视图)

最低0.47元/天 解锁文章
1466

被折叠的 条评论
为什么被折叠?



