|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
控制器通知
通常,@ExceptionHandler、@InitBinder 和 @ModelAttribute 方法仅在其所声明的 @Controller 类(或类层次结构)内生效。如果你想让这些方法具有更全局的作用范围(跨多个控制器),可以将它们声明在一个使用 @ControllerAdvice 或 @RestControllerAdvice 注解的类中。
@ControllerAdvice 注解本身带有 @Component 注解,这意味着此类可以通过组件扫描注册为 Spring Bean。@RestControllerAdvice 是一个组合注解,同时标注了 @ControllerAdvice 和 @ResponseBody,本质上表示 @ExceptionHandler 方法会通过消息转换直接渲染到响应体中(而不是通过视图解析或模板渲染)。
在启动时,用于处理 @RequestMapping 和 @ExceptionHandler 方法的基础设施类会检测带有 @ControllerAdvice 注解的 Spring Bean,并在运行时应用它们的方法。全局的 @ExceptionHandler 方法(来自 @ControllerAdvice)会在本地方法(来自 @Controller)之后被应用。相比之下,全局的 @ModelAttribute 和 @InitBinder 方法则会在本地方法之前被应用。
默认情况下,@ControllerAdvice 方法会应用于每个请求(即所有控制器),
但你可以通过在注解上使用属性来将其限定为控制器的一个子集,如下例所示:
-
Java
-
Kotlin
// Target all Controllers annotated with @RestController
@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}
// Target all Controllers within specific packages
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}
// Target all Controllers assignable to specific classes
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class ExampleAdvice3 {}
// Target all Controllers annotated with @RestController
@ControllerAdvice(annotations = [RestController::class])
public class ExampleAdvice1 {}
// Target all Controllers within specific packages
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}
// Target all Controllers assignable to specific classes
@ControllerAdvice(assignableTypes = [ControllerInterface::class, AbstractController::class])
public class ExampleAdvice3 {}
前一个示例中的选择器是在运行时评估的,如果大量使用,可能会对性能产生负面影响。请参阅
@ControllerAdvice
javadoc 以获取更多详细信息。