Spring MVC'nin böyle davranması beklenir mi?
Spring 4.3.7'den itibaren, Spring MVC şu şekilde davranır: HandlerExceptionResolver
İşleyici yöntemleri tarafından oluşturulan istisnaları işlemek için örnekleri kullanır .
Varsayılan olarak, web MVC yapılandırması tek bir HandlerExceptionResolver
bean kaydeder , a HandlerExceptionResolverComposite
,
diğerlerinin listesine delegeler HandlerExceptionResolvers
.
Bu diğer çözücüler
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
bu sırayla kayıtlı. Bu sorunun amacı için sadece önemsiyoruz ExceptionHandlerExceptionResolver
.
Bir AbstractHandlerMethodExceptionResolver
aracılığıyla özel durumları çözer @ExceptionHandler
yöntemlerle.
Bağlam başlatma sırasında Spring, algıladığı ControllerAdviceBean
her @ControllerAdvice
açıklamalı sınıf için bir tane oluşturur . ExceptionHandlerExceptionResolver
Bağlamdan bunlar almak ve bunları kullanarak kullanarak sıralanır AnnotationAwareOrderComparator
hangi
Statik olarak tanımlanmış bir açıklama değerini (varsa) geçersiz kılan Sıralı bir örnek tarafından sağlanan bir sipariş değeriyle OrderComparator
Spring'in Ordered
arayüzünü @Order
ve @Priority
ek açıklamaları destekleyen bir uzantısıdır .
Daha sonra ExceptionHandlerMethodResolver
, bu ControllerAdviceBean
örneklerin her biri için bir tane kaydeder (mevcut @ExceptionHandler
yöntemleri, işlemesi gereken istisna türleriyle eşleme ). Bunlar nihayet aynı sırayla a'ya eklenir LinkedHashMap
(yineleme sırasını korur).
Bir istisna meydana geldiğinde, ExceptionHandlerExceptionResolver
bunları yineleyecek ExceptionHandlerMethodResolver
ve istisnayı işleyebilen ilkini kullanacaktır.
Yani buradaki nokta şudur: eğer @ControllerAdvice
bir @ExceptionHandler
for a sahipseniz, Exception
başka bir @ControllerAdvice
sınıftan önce @ExceptionHandler
daha özel bir istisna ile kayıt olursanız IOException
, o ilk çağrılır. Daha önce belirtildiği gibi, kendi alarak bu kaydı sırasını kontrol edebilir @ControllerAdvice
açıklamalı sınıf uygulamak Ordered
veya açıklayarak @Order
veya @Priority
ve ona uygun bir değer veren.
@ExceptionHandler
yöntem olması durumunda@ControllerAdvice
, atılan istisnanın en spesifik üst sınıfını işleyen yöntem seçilir.