Ответ
@ControllerAdvice — это аннотация Spring, которая позволяет создать глобальный, компонентный обработчик исключений, перехватчик данных (ModelAttribute) и инициаторы привязки (InitBinder), применяемый ко всем или к выбранной группе контроллеров.
Основные сценарии использования:
-
Глобальная обработка исключений (Global Exception Handling) — самый частый случай.
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(UserNotFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) @ResponseBody public ErrorResponse handleUserNotFound(UserNotFoundException ex) { return new ErrorResponse("USER_NOT_FOUND", ex.getMessage()); } @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public ErrorResponse handleValidationExceptions(MethodArgumentNotValidException ex) { // Обработка ошибок валидации @Valid return new ErrorResponse("VALIDATION_ERROR", ex.getBindingResult().toString()); } @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody public ErrorResponse handleAllUncaughtException(Exception ex) { return new ErrorResponse("INTERNAL_ERROR", "An unexpected error occurred"); } } -
Глобальная инициализация данных модели (
@ModelAttribute).@ControllerAdvice public class GlobalModelAdvice { @ModelAttribute("currentYear") public int addCurrentYear() { return Year.now().getValue(); // Добавит атрибут "currentYear" в модель каждого контроллера } } -
Глобальная настройка привязки данных (
@InitBinder).@ControllerAdvice public class GlobalBinderAdvice { @InitBinder public void initBinder(WebDataBinder binder) { // Запрет привязки поля "id" из запроса binder.setDisallowedFields("id"); // Настройка форматирования дат и т.д. } }
Детализация области действия:
Можно ограничить действие @ControllerAdvice конкретными пакетами, классами контроллеров или аннотациями.
// Только для контроллеров в пакете "com.example.web"
@ControllerAdvice("com.example.web")
// Только для контроллеров, аннотированных @RestController
@ControllerAdvice(annotations = RestController.class)
// Только для указанных классов контроллеров
@ControllerAdvice(assignableTypes = {UserController.class, AdminController.class})
Итог: @ControllerAdvice — это мощный инструмент для централизации и повторного использования кода, общего для многих контроллеров, что делает приложение чище и удобнее в поддержке.