で注釈が付けられた複数のクラスがあり@ControllerAdvice
、それぞれに の@ExceptionHandler
メソッドがあります。
Exception
これ以上の特定のハンドラーが見つからない場合は、これを使用するという意図で処理します。
残念なことに、Spring MVC は、より具体的なケース (など)Exception
ではなく、最も一般的なケース ( ) を常に使用しているようです。IOException
これは、Spring MVC が期待する動作でしょうか? 私は、各ExceptionMapper
(同等のコンポーネント) を評価して、処理する宣言された型がスローされた例外からどれだけ離れているかを判断し、常に最も近い祖先を使用する Jersey のパターンをエミュレートしようとしています。
ベストアンサー1
これは Spring MVC が期待通りの動作をするのでしょうか?
Spring 4.3.7では、Spring MVCは次のように動作します。HandlerExceptionResolver
ハンドラー メソッドによってスローされた例外を処理するインスタンス。
デフォルトでは、Web MVC構成は単一のHandlerExceptionResolver
Beanを登録します。HandlerExceptionResolverComposite
、 どれの
他のリストに委任します
HandlerExceptionResolvers
。
他のリゾルバは
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
この質問の目的のために、私たちは次のことだけを気にしていますExceptionHandlerExceptionResolver
。
メソッド
AbstractHandlerMethodExceptionResolver
を通じて例外を解決する@ExceptionHandler
。
コンテキストの初期化時に、SpringはControllerAdviceBean
それぞれ@ControllerAdvice
検出された注釈付きクラス。はExceptionHandlerExceptionResolver
コンテキストからこれらを取得し、を使用して並べ替えます。AnnotationAwareOrderComparator
どれの
OrderComparator
は、Spring のOrdered
インターフェースと および@Order
アノテーションをサポートするの拡張であり@Priority
、Ordered インスタンスによって提供される順序値が、静的に定義されたアノテーション値 (存在する場合) をオーバーライドします。
その後、ExceptionHandlerMethodResolver
ControllerAdviceBean
これらのインスタンスごとに(利用可能な@ExceptionHandler
メソッドを、それらが処理することを意図している例外タイプにマッピングします)。これらは最終的に同じ順序でLinkedHashMap
(反復順序が保持される) に追加されます。
例外が発生すると、ExceptionHandlerExceptionResolver
これらを反復処理しExceptionHandlerMethodResolver
、例外を処理できる最初のものを使用します。
ここでのポイントは、のようなより具体的な例外に対して を持つ別のクラスより前に登録される を持つ がある場合、@ControllerAdvice
最初の例外が呼び出されるということです。前述のように、アノテーションを付与したクラスに実装させることで、登録順序を制御できます。@ExceptionHandler
Exception
@ControllerAdvice
@ExceptionHandler
IOException
@ControllerAdvice
Ordered
または注釈を付ける@Order
または@Priority
適切な値を与えます。