Controller Advice
@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
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.
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.
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
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.