Методы, аннотированные @ExceptionHandler
, @InitBinder
и @ModelAttribute
применяются только к классу, помеченному аннотацией @Controller
, или к иерархии классов, в которых они объявлены. Если вместо этого они объявлены в классе, аннотированном @ControllerAdvice
или @RestControllerAdvice
, то они применяются к любому контроллеру. Более того, начиная с версии 5.3, методы, аннотированные @ExceptionHandler
в @ControllerAdvice
можно использовать для обработки исключений из любого помеченного аннотацией @Controller
обработчика или любого другого обработчика.
Аннотация @ControllerAdvice
мета-анотирована при помощи аннотации @Component
и поэтому может быть зарегистрирована как бин Spring через сканирование компонентов. Аннотация @RestControllerAdvice
мета-анотирована при помощи аннотации @ControllerAdvice
и аннотации @ResponseBody
, и это означает, что методы, помеченные аннотацией @ExceptionHandler
, будут иметь свое возвращаемое значение, визуализируемое через преобразование сообщения тела ответа, а не через HTML-представления.
При запуске RequestMappingHandlerMapping
и ExceptionHandlerExceptionResolver
обнаруживают снабженные Advice бины контроллера и применяют их во время выполнения. Глобальные методы, помеченные аннотацией @ExceptionHandler
, из @ControllerAdvice
, применяются после локальных, из @Controller
. И наоборот, глобальные методы с аннотациями @ModelAttribute
и @InitBinder
применяются перед локальными.
Аннотация @ControllerAdvice
имеет атрибуты, которые позволяют сузить набор контроллеров и обработчиков, к которым они применяются. Например:
// Делаем целью все контроллеры, аннотированные при помощи @RestController
@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}
// Делаем целью все контроллеры в определенных пакетах
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}
// Делаем целью все контроллеры, назначаемые определенным классам
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class ExampleAdvice3 {}
// Делаем целью все контроллеры, аннотированные при помощи @RestController
@ControllerAdvice(annotations = [RestController::class])
class ExampleAdvice1
// Делаем целью все контроллеры в определенных пакетах
@ControllerAdvice("org.example.controllers")
class ExampleAdvice2
// Делаем целью все контроллеры, назначаемые определенным классам
@ControllerAdvice(assignableTypes = [ControllerInterface::class, AbstractController::class])
class ExampleAdvice3
Селекторы в предыдущем примере вычисляются во время выполнения и могут негативно повлиять на производительность при широком использовании. Более подробную информацию смотрите в javadoc по аннотации @ControllerAdvice
.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ