Spring Web Reactive | 1. Spring WebFlux | 1.3. DispatcherHandler

Web MVC

Spring MVCと同様に、Spring WebFluxはfront controllerパターンを中心に設計されています。中心となるWebHandlerであるDispatcherHandlerが共通のリクエスト処理アルゴリズムを提供し、設定可能なdelegateコンポーネントが実際の処理を行います。

DispatcherHandlerはSpring設定から必要なdelegateを検出します。Spring beanとして実行時contextへアクセスするためにApplicationContextAwareを実装します。webHandlerというbean名で宣言すると、WebHttpHandlerBuilderWebHandler APIに従って処理chainを構築します。

一般的なWebFlux設定には次が含まれます。

Java:

ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context).build();

Kotlin:

val context: ApplicationContext = ...
val handler = WebHttpHandlerBuilder.applicationContext(context).build()

生成されたHttpHandlerserver adapterで使用できます。

1.3.1. 特別なBean Type

DispatcherHandlerはリクエスト処理とレスポンス描画を特別なSpring管理beanへ委譲します。標準実装は組み込まれていますが、カスタマイズ、拡張、置換できます。

Bean type 説明
HandlerMapping 実装ごとの条件でリクエストをhandlerへ対応付けます。主な実装は@RequestMapping用のRequestMappingHandlerMapping、関数型endpoint用のRouterFunctionMapping、明示的なURI pattern用のSimpleUrlHandlerMappingです。
HandlerAdapter 呼び出し方法の詳細をDispatcherHandlerから分離し、対応するhandlerを実行します。
HandlerResultHandler 実行結果を処理してレスポンスを完成させます。Result Handlingを参照してください。

1.3.2. WebFlux設定

必要なインフラbeanを直接宣言できますが、通常はWebFlux設定が適切な出発点です。必要なbeanと高水準のカスタマイズcallbackを提供します。

Spring BootはWebFlux設定に基づいてSpring WebFluxを構成し、便利な追加オプションを提供します。

1.3.3. 処理

  • HandlerMappingから一致するhandlerを探し、最初の一致を使用します。
  • 適切なHandlerAdapterでhandlerを呼び出し、HandlerResultを受け取ります。
  • 適切なHandlerResultHandlerへ渡し、直接レスポンスを作成するかviewを描画します。

1.3.4. 結果処理

handlerの戻り値は追加contextと共にHandlerResultへ包まれ、最初に対応するHandlerResultHandlerへ渡されます。

Result handler type 戻り値 標準順序
ResponseEntityResultHandler 主に@ControllerResponseEntity 0
ServerResponseResultHandler 主に関数型endpointのServerResponse 0
ResponseBodyResultHandler @ResponseBodyまたは@RestControllerの戻り値。 100
ViewResolutionResultHandler CharSequenceViewModelMapRendering、model属性として扱うその他のobject。 Integer.MAX_VALUE

1.3.5. 例外

HandlerResultは、handler呼び出しまたは戻り値処理の失敗に対応するerror処理関数を提供します。リアクティブ型がデータを生成する前ならレスポンスstatusも変更できます。

これにより@Controller内の@ExceptionHandlerを利用できます。ただしMVCとは異なり、handler選択前の例外を@ControllerAdviceで処理できません。

1.3.6. View Resolution

view resolutionは、特定のview技術へ依存せずHTML templateとmodelでレスポンスを描画します。専用のHandlerResultHandlerViewResolverで論理view名をViewへ対応付けます。

Handling

  • String, CharSequence: 設定済みViewResolverで解決する論理view名。
  • void: リクエストpathに基づく標準view名。view名がない場合や非同期戻り値が空で完了した場合も同様です。
  • Rendering: view resolution用API。
  • Model, Map: 追加model属性。
  • その他: 単純型以外はmodel属性になります。名前は@ModelAttributeまたはclass名から導出します。

modelは非同期リアクティブ型も保持できます。AbstractViewは描画前に解決し、単一値型は一つまたは空の値、Flux<T>などの複数値型はList<T>になります。

Redirecting

redirect: prefixでredirectできます。redirect:/some/resourceは現在のアプリケーションに対する相対URL、redirect:https://example.com/arbitrary/pathは絶対URLです。RedirectViewまたはRendering.redirectTo("abc").build()を返す場合と同じです。

Content Negotiation

ViewResolutionResultHandlerは要求media typeと各Viewの対応typeを比較し、最初に一致したviewを選択します。JSONやXMLにはHttpMessageWriterで描画するHttpMessageWriterViewを利用できます。