複数の @ControllerAdvice @ExceptionHandlers の優先順位を設定する 質問する

複数の @ControllerAdvice @ExceptionHandlers の優先順位を設定する 質問する

で注釈が付けられた複数のクラスがあり@ControllerAdvice、それぞれに の@ExceptionHandlerメソッドがあります。

Exceptionこれ以上の特定のハンドラーが見つからない場合は、これを使用するという意図で処理します。

残念なことに、Spring MVC は、より具体的なケース (など)Exceptionではなく、最も一般的なケース ( ) を常に使用しているようです。IOException

これは、Spring MVC が期待する動作でしょうか? 私は、各ExceptionMapper(同等のコンポーネント) を評価して、処理する宣言された型がスローされた例外からどれだけ離れているかを判断し、常に最も近い祖先を使用する Jersey のパターンをエミュレートしようとしています。

ベストアンサー1

これは Spring MVC が期待通りの動作をするのでしょうか?

Spring 4.3.7では、Spring MVCは次のように動作します。HandlerExceptionResolverハンドラー メソッドによってスローされた例外を処理するインスタンス。

デフォルトでは、Web MVC構成は単一のHandlerExceptionResolverBeanを登録します。HandlerExceptionResolverComposite、 どれの

他のリストに委任しますHandlerExceptionResolvers

他のリゾルバは

  1. ExceptionHandlerExceptionResolver
  2. ResponseStatusExceptionResolver
  3. DefaultHandlerExceptionResolver

この質問の目的のために、私たちは次のことだけを気にしていますExceptionHandlerExceptionResolver

メソッドAbstractHandlerMethodExceptionResolverを通じて例外を解決する@ExceptionHandler

コンテキストの初期化時に、SpringはControllerAdviceBeanそれぞれ@ControllerAdvice検出された注釈付きクラス。はExceptionHandlerExceptionResolverコンテキストからこれらを取得し、を使用して並べ替えます。AnnotationAwareOrderComparatorどれの

OrderComparatorは、Spring のOrderedインターフェースと および@Orderアノテーションをサポートするの拡張であり@Priority、Ordered インスタンスによって提供される順序値が、静的に定義されたアノテーション値 (存在する場合) をオーバーライドします。

その後、ExceptionHandlerMethodResolverControllerAdviceBeanこれらのインスタンスごとに(利用可能な@ExceptionHandlerメソッドを、それらが処理することを意図している例外タイプにマッピングします)。これらは最終的に同じ順序でLinkedHashMap(反復順序が保持される) に追加されます。

例外が発生すると、ExceptionHandlerExceptionResolverこれらを反復処理しExceptionHandlerMethodResolver、例外を処理できる最初のものを使用します。

ここでのポイントは、のようなより具体的な例外に対して を持つ別のクラスより前に登録される を持つ がある場合、@ControllerAdvice最初の例外が呼び出されるということです。前述のように、アノテーションを付与したクラスに実装させることで、登録順序を制御できます。@ExceptionHandlerException@ControllerAdvice@ExceptionHandlerIOException@ControllerAdviceOrderedまたは注釈を付ける@Orderまたは@Priority適切な値を与えます。

おすすめ記事