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 HandlerExceptionResolverInstanzen, um Ausnahmen zu behandeln, die von Handler-Methoden ausgelöst werden.
Standardmäßig registriert die Web-MVC-Konfiguration eine einzelne HandlerExceptionResolverBean, 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 @ExceptionHandlerMethoden auflöst .
Bei der Kontextinitialisierung generiert Spring ControllerAdviceBeanfür jede mit @ControllerAdviceAnmerkungen versehene Klasse eine. Das ExceptionHandlerExceptionResolverruft diese aus dem Kontext ab und sortiert sie mit AnnotationAwareOrderComparatorwelcher
ist eine Erweiterung OrderComparator, die die Spring- Ordered
Schnittstelle sowie die Annotationen @Orderund und unterstützt @Priority, wobei ein Bestellwert, der von einer geordneten Instanz bereitgestellt wird, einen statisch definierten Annotationswert (falls vorhanden) überschreibt.
Anschließend wird ExceptionHandlerMethodResolverfür jede dieser ControllerAdviceBeanInstanzen eine registriert (Zuordnung der verfügbaren @ExceptionHandlerMethoden 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, ExceptionHandlerExceptionResolverdurchläuft der diese diese ExceptionHandlerMethodResolverund verwendet die erste, die die Ausnahme behandeln kann.
Der Punkt hier ist also: Wenn Sie ein @ControllerAdvicemit einem @ExceptionHandlerfür das haben Exception, wird es vor einer anderen @ControllerAdviceKlasse mit einem @ExceptionHandlerfü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 @ControllerAdviceAnmerkungen versehene Klasse implementieren Orderedoder mit @Orderoder mit Anmerkungen versehen @Priorityund ihr einen geeigneten Wert geben.
@ExceptionHandlerMethoden innerhalb von a@ControllerAdvicediejenige ausgewählt, die die spezifischste Oberklasse der ausgelösten Ausnahme behandelt.