DispatcherHandler

Spring WebFlux は、Spring MVC と同様に、フロントコントローラーパターンを中心に設計されており、主要な WebHandler である DispatcherHandler がリクエスト処理の共有アルゴリズムを提供し、実際の作業は構成可能なデリゲートコンポーネントによって実行されます。このモデルは柔軟で、多様なワークフローをサポートします。

DispatcherHandler は、Spring 構成から必要なデリゲートコンポーネントを検出します。また、Spring Bean 自体になるように設計されており、実行されるコンテキストにアクセスするために ApplicationContextAware を実装しています。DispatcherHandler が webHandler という Bean 名で宣言されている場合、WebHandler API に従って、リクエスト処理チェーンをまとめる WebHttpHandlerBuilder (Javadoc) によって検出されます。

WebFlux アプリケーションの Spring 構成には通常、次のものが含まれます。

次の例が示すように、処理はチェーンを構築するために WebHttpHandlerBuilder に与えられます。

  • Java

  • Kotlin

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

結果として得られる HttpHandler は、サーバーアダプターで使用できるようになります。

特別な Bean 型

DispatcherHandler は、リクエストを処理して適切なレスポンスをレンダリングするために特別な Bean に委譲します。「特別な Bean」とは、WebFlux フレームワーク契約を実装する Spring 管理の Object インスタンスを意味します。通常、これらにはビルトイン契約が付属していますが、プロパティをカスタマイズしたり、拡張したり、置き換えたりすることができます。

次の表に、DispatcherHandler によって検出された特別な Bean を示します。下位レベルで検出された他の Bean もいくつかあることに注意してください(Web ハンドラー API の特別な Bean 型を参照)。

Bean 型 説明

HandlerMapping

リクエストをハンドラーにマップします。マッピングはいくつかの条件に基づいており、その詳細は HandlerMapping の実装によって異なります。アノテーション付きコントローラー、単純な URL パターンマッピングなど。

主な HandlerMapping 実装は、@RequestMapping アノテーション付きメソッドの RequestMappingHandlerMapping、関数エンドポイントルートの RouterFunctionMapping、URI パスパターンと WebHandler インスタンスの明示的な登録の SimpleUrlHandlerMapping です。

HandlerAdapter

ハンドラーが実際に呼び出される方法に関係なく、DispatcherHandler がリクエストにマップされたハンドラーを呼び出すのに役立ちます。例: アノテーション付きコントローラーを呼び出すには、アノテーションを解決する必要があります。HandlerAdapter の主な目的は、そのような詳細から DispatcherHandler を保護することです。

HandlerResultHandler

ハンドラー呼び出しからの結果を処理し、レスポンスを確定します。結果処理を参照してください。

WebFlux 構成

アプリケーションは、リクエストの処理に必要なインフラストラクチャ Bean(Web ハンドラー API および DispatcherHandler にリストされている)を宣言できます。ただし、ほとんどの場合、WebFlux 構成が最適な出発点です。必要な Bean を宣言し、それをカスタマイズするための高レベルの構成コールバック API を提供します。

Spring Boot は WebFlux 構成に依存して Spring WebFlux を構成し、さらに多くの便利なオプションを提供します。

処理

DispatcherHandler は、リクエストを次のように処理します。

  • 各 HandlerMapping は、一致するハンドラーを見つけるように求められ、最初の一致が使用されます。

  • ハンドラーが見つかると、適切な HandlerAdapter を介して実行され、実行からの戻り値を HandlerResult として公開します。

  • HandlerResult は適切な HandlerResultHandler に渡され、レスポンスに直接書き込むか、ビューを使用してレンダリングすることで処理を完了します。

結果処理

HandlerAdapter を介したハンドラーの呼び出しからの戻り値は、追加のコンテキストとともに HandlerResult としてラップされ、そのサポートを要求する最初の HandlerResultHandler に渡されます。次の表に、利用可能な HandlerResultHandler 実装を示します。これらはすべて WebFlux 構成で宣言されています。

結果ハンドラーの型 戻り値 デフォルトの順序

ResponseEntityResultHandler

ResponseEntity, typically from @Controller instances.

0

ServerResponseResultHandler

ServerResponse, typically from functional endpoints.

0

ResponseBodyResultHandler

@ResponseBody メソッドまたは @RestController クラスからの戻り値を処理します。

100

ViewResolutionResultHandler

CharSequence, View (Javadoc) , Model (Javadoc) , Map, Rendering (Javadoc) , or any other Object is treated as a model attribute.

See also View Resolution.

Integer.MAX_VALUE

例外

HandlerAdapter 実装は、コントローラーメソッドなどのリクエストハンドラーの呼び出しによる内部例外を処理できます。ただし、リクエストハンドラーが非同期値を返す場合は、例外が延期されることがあります。

HandlerAdapter は、それが返す HandlerResult で設定された DispatchExceptionHandler として、その例外処理メカニズムを公開する場合があります。それが設定されると、DispatcherHandler はそれを結果の処理にも適用します。

HandlerAdapter は、DispatchExceptionHandler を実装することもできます。その場合、DispatcherHandler は、ハンドラーがマップされる前、たとえばハンドラーマッピング中、またはそれより前、たとえば WebFilter で発生する例外にそれを適用します。

「アノテーション付きコントローラー」セクションの例外または WebHandler API セクションの例外も参照してください。

ビューリゾルバー

ビューリゾルバーにより、特定のビューテクノロジに縛られることなく、HTML テンプレートとモデルを使用してブラウザーにレンダリングできます。Spring WebFlux では、ViewResolver インスタンスを使用してストリング(論理ビュー名を表す)を View インスタンスにマップする専用 HandlerResultHandler を介して、ビューリゾルバーがサポートされています。次に、View を使用してレスポンスをレンダリングします。

Web アプリケーションでは、このユースケースをサポートするためにレンダリングライブラリを表示を使用する必要があります。

ハンドリング

ViewResolutionResultHandler に渡される HandlerResult には、ハンドラーからの戻り値と、リクエスト処理中に追加された属性を含むモデルが含まれます。戻り値は次のいずれかとして処理されます。

  • StringCharSequence: 構成された ViewResolver 実装のリストを通じて View に解決される論理ビュー名。

  • void: リクエストパスに基づいて、先頭と末尾のスラッシュを除いたデフォルトのビュー名を選択し、View に解決します。ビュー名が指定されなかった場合(モデル属性が返された場合など)、または非同期の戻り値(たとえば、空の Mono が完了した場合)でも同じことが起こります。

  • レンダリング (Javadoc) : ビュー解決シナリオの API。コード補完を使用して IDE のオプションを調べましょう。

  • ModelMap: リクエストのモデルに追加される追加のモデル属性。

  • 他: その他の戻り値(BeanUtils#isSimpleProperty (Javadoc) によって決定される単純型を除く)は、モデルに追加されるモデル属性として扱われます。ハンドラーメソッド @ModelAttribute アノテーションが存在しない限り、属性名は規約 (Javadoc) を使用してクラス名から派生します。

モデルには、非同期のリアクティブ型を含めることができます(たとえば、Reactor または RxJava から)。レンダリングの前に、AbstractView はそのようなモデル属性を具体的な値に解決し、モデルを更新します。単一値のリアクティブ型は単一の値または値なし(空の場合)に解決され、複数値のリアクティブ型(たとえば Flux<T>)は収集されて List<T> に解決されます。

ビューリゾルバーを構成するには、ViewResolutionResultHandler Bean を Spring 構成に追加するだけです。WebFlux 構成は、ビューリゾルバー専用の構成 API を提供します。

Spring WebFlux と統合されたビューテクノロジーの詳細については、ビューテクノロジーを参照してください。

リダイレクト

ビュー名の特別な redirect: プレフィックスを使用すると、リダイレクトを実行できます。UrlBasedViewResolver (およびサブクラス)は、これをリダイレクトが必要な命令として認識します。ビュー名の残りはリダイレクト URL です。

最終的な効果は、コントローラーが RedirectView または Rendering.redirectTo("abc").build() を返した場合と同じですが、コントローラー自体が論理ビュー名の観点から動作できるようになりました。redirect:/some/resource などのビュー名は現在のアプリケーションに関連していますが、redirect:https://example.com/arbitrary/path などのビュー名は絶対 URL にリダイレクトされます。

サーブレットスタックとは異なり、Spring、WebFlux は "FORWARD" ディスパッチをサポートしていないため、結果として forward: プレフィックスはサポートされません。

コンテンツネゴシエーション

ViewResolutionResultHandler はコンテンツネゴシエーションをサポートしています。リクエストメディア型と、選択した各 View でサポートされているメディア型を比較します。リクエストされたメディア型をサポートする最初の View が使用されます。

JSON や XML などのメディア型をサポートするために、Spring WebFlux は HttpMessageWriterView を提供します。これは、HttpMessageWriter を介してレンダリングする特別な View です。通常、これらは WebFlux の設定を介してデフォルトビューとして設定します。リクエストされたメディア型に一致する場合、デフォルトビューが常に選択され、使用されます。