Controller Advice
@ExceptionHandler
、@InitBinder
和 @ModelAttribute
方法仅适用于它们声明的 @Controller
类或类层次结构。相反,如果在 @ControllerAdvice
或 @RestControllerAdvice
类中声明它们,则它们将应用于任何控制器。此外,从 5.3 起,@ControllerAdvice
中的 @ExceptionHandler
方法可用于处理来自任何 @Controller
或任何其他处理程序的异常。
@ExceptionHandler
, @InitBinder
, and @ModelAttribute
methods apply only to the
@Controller
class, or class hierarchy, in which they are declared. If, instead, they
are declared in an @ControllerAdvice
or @RestControllerAdvice
class, then they apply
to any controller. Moreover, as of 5.3, @ExceptionHandler
methods in @ControllerAdvice
can be used to handle exceptions from any @Controller
or any other handler.
@ControllerAdvice
通过 @Component
进行元注释,因此可以通过 component scanning 注册为 Spring Bean。@RestControllerAdvice
通过 @ControllerAdvice
和 @ResponseBody
进行元注释,这意味着 @ExceptionHandler
方法将通过响应主体消息转换渲染其返回值,而不是通过 HTML 视图渲染。
@ControllerAdvice
is meta-annotated with @Component
and therefore can be registered as
a Spring bean through component scanning
. @RestControllerAdvice
is meta-annotated with @ControllerAdvice
and @ResponseBody
, and that means @ExceptionHandler
methods will have their return
value rendered via response body message conversion, rather than via HTML views.
在启动时,RequestMappingHandlerMapping
和 ExceptionHandlerExceptionResolver
会检测控制器建议 bean 并将其应用于运行时。来自 @ControllerAdvice
的全局 @ExceptionHandler
方法在来自 @Controller
的本地方法_之后_应用。相比之下,全局 @ModelAttribute
和 @InitBinder
方法在本地方法_之前_应用。
On startup, RequestMappingHandlerMapping
and ExceptionHandlerExceptionResolver
detect
controller advice beans and apply them at runtime. Global @ExceptionHandler
methods,
from an @ControllerAdvice
, are applied after local ones, from the @Controller
.
By contrast, global @ModelAttribute
and @InitBinder
methods are applied before local ones.
@ControllerAdvice
注解具有可缩小其所应用的控制器和处理程序集的属性。例如:
The @ControllerAdvice
annotation has attributes that let you narrow the set of controllers
and handlers that they apply to. For example:
-
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 以获取更多详细信息。
The selectors in the preceding example are evaluated at runtime and may negatively impact
performance if used extensively. See the
@ControllerAdvice
javadoc for more details.