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
.