Controller Advice

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

@ControllerAdvice 通过 @Component 进行元注释,因此可以通过 component scanning 注册为 Spring Bean。@RestControllerAdvice 通过 @ControllerAdvice@ResponseBody 进行元注释,这意味着 @ExceptionHandler 方法将通过响应主体消息转换渲染其返回值,而不是通过 HTML 视图渲染。

在启动时,RequestMappingHandlerMappingExceptionHandlerExceptionResolver 会检测控制器建议 bean 并将其应用于运行时。来自 @ControllerAdvice 的全局 @ExceptionHandler 方法在来自 @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])
class ExampleAdvice1

// Target all Controllers within specific packages
@ControllerAdvice("org.example.controllers")
class ExampleAdvice2

// Target all Controllers assignable to specific classes
@ControllerAdvice(assignableTypes = [ControllerInterface::class, AbstractController::class])
class ExampleAdvice3

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