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