Würde man erwarten, dass sich Spring MVC so verhält?
Ab Spring 4.3.7 verhält sich Spring MVC folgendermaßen: Es verwendet HandlerExceptionResolver
Instanzen, um Ausnahmen zu behandeln, die von Handler-Methoden ausgelöst werden.
Standardmäßig registriert die Web-MVC-Konfiguration eine einzelne HandlerExceptionResolver
Bean, a HandlerExceptionResolverComposite
, die
delegiert an eine Liste von anderen HandlerExceptionResolvers
.
Diese anderen Resolver sind
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
in dieser Reihenfolge registriert. Für den Zweck dieser Frage kümmern wir uns nur ExceptionHandlerExceptionResolver
.
Eine AbstractHandlerMethodExceptionResolver
, die Ausnahmen durch @ExceptionHandler
Methoden auflöst .
Bei der Kontextinitialisierung generiert Spring ControllerAdviceBean
für jede mit @ControllerAdvice
Anmerkungen versehene Klasse eine. Das ExceptionHandlerExceptionResolver
ruft diese aus dem Kontext ab und sortiert sie mit AnnotationAwareOrderComparator
welcher
ist eine Erweiterung OrderComparator
, die die Spring- Ordered
Schnittstelle sowie die Annotationen @Order
und und unterstützt @Priority
, wobei ein Bestellwert, der von einer geordneten Instanz bereitgestellt wird, einen statisch definierten Annotationswert (falls vorhanden) überschreibt.
Anschließend wird ExceptionHandlerMethodResolver
für jede dieser ControllerAdviceBean
Instanzen eine registriert (Zuordnung der verfügbaren @ExceptionHandler
Methoden zu den Ausnahmetypen, die behandelt werden sollen). Diese werden schließlich in derselben Reihenfolge zu a hinzugefügt LinkedHashMap
(wodurch die Iterationsreihenfolge erhalten bleibt).
Wenn eine Ausnahme auftritt, ExceptionHandlerExceptionResolver
durchläuft der diese diese ExceptionHandlerMethodResolver
und verwendet die erste, die die Ausnahme behandeln kann.
Der Punkt hier ist also: Wenn Sie ein @ControllerAdvice
mit einem @ExceptionHandler
für das haben Exception
, wird es vor einer anderen @ControllerAdvice
Klasse mit einem @ExceptionHandler
für eine spezifischere Ausnahme registriert , wie zum Beispiel IOException
, dass das erste aufgerufen wird. Wie bereits erwähnt, können Sie diese Registrierungsreihenfolge steuern, indem Sie Ihre mit @ControllerAdvice
Anmerkungen versehene Klasse implementieren Ordered
oder mit @Order
oder mit Anmerkungen versehen @Priority
und ihr einen geeigneten Wert geben.
@ExceptionHandler
Methoden innerhalb von a@ControllerAdvice
diejenige ausgewählt, die die spezifischste Oberklasse der ausgelösten Ausnahme behandelt.