Методы, аннотированные @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 имеет атрибуты, которые позволяют сузить набор контроллеров и обработчиков, к которым они применяются. Например:

Java
// Делаем целью все контроллеры, аннотированные при помощи @RestController
@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}
// Делаем целью все контроллеры в определенных пакетах
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}
// Делаем целью все контроллеры, назначаемые определенным классам
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class ExampleAdvice3 {}
Kotlin
// Делаем целью все контроллеры, аннотированные при помощи @RestController
@ControllerAdvice(annotations = [RestController::class])
class ExampleAdvice1
// Делаем целью все контроллеры в определенных пакетах
@ControllerAdvice("org.example.controllers")
class ExampleAdvice2
// Делаем целью все контроллеры, назначаемые определенным классам
@ControllerAdvice(assignableTypes = [ControllerInterface::class, AbstractController::class])
class ExampleAdvice3

Селекторы в предыдущем примере вычисляются во время выполнения и могут негативно повлиять на производительность при широком использовании. Более подробную информацию смотрите в javadoc по аннотации @ControllerAdvice.