Los métodos anotados con @ExceptionHandler
, @InitBinder
y @ModelAttribute
se aplican solo a la clase marcada con anotación de @Controller
, o a la jerarquía de clases en las que están declarados. Si, en cambio, se declaran en una clase anotada con @ControllerAdvice
o @RestControllerAdvice
, entonces se aplican a cualquier controlador. Además, a partir de la versión 5.3, los métodos anotados con @ExceptionHandler
en @ControllerAdvice
se pueden usar para manejar excepciones de cualquier controlador marcado con @Controller
. anotación o cualquier otro controlador.
La @ControllerAdvice
está metaanotada con la anotación @Component
y, por lo tanto, se puede registrar como un Spring Bean mediante el escaneo de componentes. La anotación @RestControllerAdvice
está metaanotada con la anotación @ControllerAdvice
y la anotación @ResponseBody
, lo que significa que los métodos marcados con annotation @ExceptionHandler
tendrá su valor de retorno representado a través de la transformación del mensaje del cuerpo de la respuesta en lugar de a través de las vistas HTML.
Al inicio, RequestMappingHandlerMapping
y ExceptionHandlerExceptionResolver
detectan beans de controlador equipados con Advice y los aplican en tiempo de ejecución. Los métodos globales marcados con la anotación @ExceptionHandler
de @ControllerAdvice
se aplican después de los locales de @Controller
. Por el contrario, los métodos globales con las anotaciones @ModelAttribute
y @InitBinder
se aplican antes de los locales.
La anotación @ControllerAdvice
tiene atributos que le permiten limitar el conjunto de controladores y manejadores a los que se aplican. Por ejemplo:
// Apunte a todos los controladores anotados con @RestController
@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}
// Apunta a todos los controladores en paquetes específicos
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}
// Apunta a todos los controladores asignados a clases específicas
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class ExampleAdvice3 {}
// Apunte a todos los controladores anotados con @RestController
@ControllerAdvice(annotations = [RestController::class])
class ExampleAdvice1
// Apunta a todos los controladores en paquetes específicos
@ControllerAdvice("org.example.controllers")
class ExampleAdvice2
// Apunta a todos los controladores asignados a clases específicas
@ControllerAdvice(assignableTypes = [ControllerInterface::class, AbstractController::class])
class ExampleAdvice3
Los selectores del ejemplo anterior se evalúan en tiempo de ejecución y pueden afectar negativamente al rendimiento si se utilizan de forma extensiva. Para obtener más información, consulte la anotación javadoc @ControllerAdvice
.