Controller Advice

@ExceptionHandler@InitBinder@ModelAttribute 方法仅适用于在其中声明的 @Controller 类或类层次结构。相反,如果它们在 @ControllerAdvice@RestControllerAdvice 类中声明,则它们适用于任何控制器。@ControllerAdvice 中的 @ExceptionHandler 方法可用于处理任何 @Controller 或任何其他处理器的异常。

@ControllerAdvice@Component 元注释,因此可以通过 组件扫描 注册为 Infra bean。@RestControllerAdvice@ControllerAdvice@ResponseBody 元注释, 这意味着 @ExceptionHandler 方法的返回值将通过响应体消息转换进行渲染,而不是通过 HTML 视图。

在启动时,RequestMappingHandlerMappingExceptionHandlerExceptionResolver 检测控制器建议 bean 并在运行时应用它们。来自 @ControllerAdvice 的全局 @ExceptionHandler 方法在来自 @Controller 的局部方法之后应用。相比之下,全局的 @ModelAttribute@InitBinder 方法在局部方法之前应用。

@ControllerAdvice 注解具有属性,允许你缩小它们适用的控制器和处理器集。例如:

// 针对所有带有 @RestController 注解的控制器
@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}

// 针对特定包中的所有控制器
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}

// 针对可分配给特定类的任何控制器
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class ExampleAdvice3 {}

前述示例中的选择器在运行时评估,如果广泛使用可能会对性能产生负面影响。有关更多详细信息,请参见 @ControllerAdvice javadoc。