控制器建议
通常,@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。