Это то, как можно ожидать поведения Spring MVC?
Начиная с Spring 4.3.7, Spring MVC ведет себя следующим образом: он использует HandlerExceptionResolverэкземпляры для обработки исключений, генерируемых методами обработчика.
По умолчанию конфигурация веб-MVC регистрирует один HandlerExceptionResolverbean-компонент a HandlerExceptionResolverComposite, который
делегаты к списку других HandlerExceptionResolvers.
Остальные резолверы
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
зарегистрированы в таком порядке. Мы заботимся только об этом вопросе ExceptionHandlerExceptionResolver.
Объект, AbstractHandlerMethodExceptionResolverкоторый разрешает исключения с помощью @ExceptionHandlerметодов.
При инициализации контекста Spring будет генерировать a ControllerAdviceBeanдля каждого @ControllerAdviceобнаруженного аннотированного класса. Они ExceptionHandlerExceptionResolverбудут извлекать их из контекста и сортировать их, используя AnnotationAwareOrderComparatorwhich
является расширением , OrderComparatorкоторое поддерживает в Spring Ordered
интерфейс, а также @Orderи @Priorityаннотаций, со значением порядка , предоставленной упорядоченном например Переопределение статически определенное значение аннотаций (если таковые имеются).
Затем он зарегистрирует ExceptionHandlerMethodResolverдля каждого из этих ControllerAdviceBeanэкземпляров (сопоставив доступные @ExceptionHandlerметоды с типами исключений, которые они должны обрабатывать). Наконец, они добавляются в том же порядке к LinkedHashMap(что сохраняет порядок итераций).
Когда возникает исключение, он ExceptionHandlerExceptionResolverбудет перебирать их ExceptionHandlerMethodResolverи использовать первый, который может обработать исключение.
Итак, суть в следующем: если у вас есть объект @ControllerAdviceс @ExceptionHandlerfor, Exceptionкоторый регистрируется перед другим @ControllerAdviceклассом с @ExceptionHandlerболее конкретным исключением, например IOException, будет вызван первый класс . Как упоминалось ранее, вы можете управлять этим порядком регистрации, @ControllerAdviceреализуя свой аннотированный класс Orderedили аннотируя его с помощью @Orderили @Priorityи давая ему соответствующее значение.
@ExceptionHandlerметодов в a@ControllerAdviceвыбирается тот, который обрабатывает наиболее конкретный суперкласс созданного исключения.