Controller Advice

    @ExceptionHandler, @InitBinder, 和 @ModelAttribute 方法只适用于它们被声明的 @Controller类,或类的层次结构。如果它们被声明在 @ControllerAdvice@RestControllerAdvice 类中,那么它们就适用于任何控制器。此外,从 5.3 版本开始,@ControllerAdvice中的 @ExceptionHandler方法可以用来处理来自任何 @Controller或任何其他处理器的异常。

    @ControllerAdvice@Component进行了元注解,因此可以通过组件扫描注册为 Spring Bean。@RestControllerAdvice@ControllerAdvice@ResponseBody进行了元注解,这意味着 @ExceptionHandler方法的返回值将通过响应体信息转换呈现,而不是通过 HTML 视图。

    在启动时,RequestMappingHandlerMapping 和 ExceptionHandlerExceptionResolver 会检测控制器 advice bean 并在运行时应用它们。来自@ControllerAdvice的全局 @ExceptionHandler方法,在来自 @Controller的局部方法之后被应用。相比之下,全局的 @ModelAttribute@InitBinder方法会在本地方法之前应用。

    @ControllerAdvice注解有一些属性,可以让你缩小它们所适用的控制器和处理程序的集合。比如:

    1. // 针对所有用 @RestController 注解的控制器
    2. @ControllerAdvice(annotations = RestController.class)
    3. public class ExampleAdvice1 {}
    4. // 所有指定包中的控制器
    5. @ControllerAdvice("org.example.controllers")
    6. public class ExampleAdvice2 {}
    7. // 所有指定的控制器
    8. @ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
    9. public class ExampleAdvice3 {}

    前面例子中的选择器是在运行时评估的,如果大量使用可能会对性能产生负面影响。更多细节请参见 @ControllerAdvice javadoc