Methods annotated with @ExceptionHandler
, @InitBinder
, and @ModelAttribute
apply only to the class marked with the @Controller
annotation, or to the hierarchy of classes in which they are
declared. If instead they are declared in a class annotated with @ControllerAdvice
or @RestControllerAdvice
,
then they apply to any controller. Moreover, as of version 5.3, methods annotated with
@ExceptionHandler
in @ControllerAdvice
can be used to handle exceptions from any handler
marked with the @Controller
annotation or any other handler.
The @ControllerAdvice
annotation is meta-annotated with the @Component
annotation and can
therefore be registered as a Spring bean via component scanning. The @RestControllerAdvice
annotation
is meta-annotated with the @ControllerAdvice
annotation and the @ResponseBody
annotation,
which means that methods marked with the @ExceptionHandler
annotation will have its return value
rendered through the response body message transformation rather than through the HTML views.
At startup, RequestMappingHandlerMapping
and ExceptionHandlerExceptionResolver
detect
Advice-equipped controller beans and apply them at runtime. Global methods marked with the
@ExceptionHandler
annotation from @ControllerAdvice
are applied after local ones
from @Controller
. Conversely, global methods with @ModelAttribute
and
@InitBinder
annotations are applied before local ones.
The @ControllerAdvice
annotation has attributes that allow you to narrow the set of controllers and
handlers to which they apply. For example:
// Target all controllers annotated with @RestController
@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}
// Target all controllers in specific packages
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}
// Target all controllers assigned 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 in specific packages
@ControllerAdvice("org.example.controllers")
class ExampleAdvice2
// Target all controllers assigned to specific classes
@ControllerAdvice(assignableTypes = [ControllerInterface::class, AbstractController::class])
class ExampleAdvice3
The selectors in the previous example are evaluated at run time and can negatively impact performance if used
extensively. For more information, see the annotation javadoc @ControllerAdvice
.
GO TO FULL VERSION