DispatcherHandler
Spring WebFlux 與 Spring MVC 類似,圍繞前端控制器(front controller)模式設計,其中核心的 WebHandler
,即 DispatcherHandler
,提供了一個共享的請求處理演算法,而實際工作則由可配置的委託元件執行。這種模型靈活,支援多種工作流。
DispatcherHandler
從 Spring 配置中發現其所需的委託元件。它也被設計為一個 Spring bean,並實現了 ApplicationContextAware
介面,以便訪問其執行所在的上下文。如果 DispatcherHandler
的 bean 名稱宣告為 webHandler
,那麼它將由 WebHttpHandlerBuilder
發現,後者會組裝一個請求處理鏈,如 WebHandler
API 中所述。
WebFlux 應用中的 Spring 配置通常包含
-
bean 名稱為
webHandler
的DispatcherHandler
-
WebFilter
和WebExceptionHandler
bean -
其他
將配置提供給 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 Handler API 中的 特殊 bean 型別)。
Bean 型別 | 解釋 |
---|---|
|
將請求對映到處理器。對映基於某些標準,其詳細資訊因 主要的 |
|
幫助 |
|
處理處理器呼叫結果並完成響應。請參閱 結果處理。 |
WebFlux 配置
應用可以宣告處理請求所需的基礎設施 bean(列在 Web Handler API 和 DispatcherHandler
下)。然而,在大多數情況下,WebFlux Config 是最好的起點。它聲明瞭所需的 bean,並提供了一個更高級別的配置回撥 API 來定製它。
Spring Boot 依賴 WebFlux 配置來配置 Spring WebFlux,並提供了許多額外的便捷選項。 |
處理流程
DispatcherHandler
按以下方式處理請求
-
每個
HandlerMapping
被要求查詢匹配的處理器,並使用第一個匹配項。 -
如果找到處理器,它將透過適當的
HandlerAdapter
執行,HandlerAdapter
將執行的返回值暴露為HandlerResult
。 -
HandlerResult
被交給適當的HandlerResultHandler
,透過直接寫入響應或使用檢視渲染來完成處理。
結果處理
透過 HandlerAdapter
呼叫處理器返回的值被包裝成一個 HandlerResult
,以及一些額外的上下文,並傳遞給第一個聲稱支援它的 HandlerResultHandler
。下表顯示了可用的 HandlerResultHandler
實現,所有這些都在 WebFlux Config 中宣告。
結果處理器型別 | 返回值 | 預設順序 |
---|---|---|
|
|
0 |
|
|
0 |
|
處理來自 `@ResponseBody` 方法或 `@RestController` 類的返回值。 |
100 |
|
另請參閱 檢視解析。 |
|
異常
HandlerAdapter
實現可以內部處理呼叫請求處理器(例如控制器方法)時發生的異常。然而,如果請求處理器返回非同步值,異常可能會被延遲處理。
一個 HandlerAdapter
可以將其異常處理機制作為設定在其返回的 HandlerResult
上的 DispatchExceptionHandler
暴露出來。設定後,DispatcherHandler
也會將其應用於結果的處理。
一個 HandlerAdapter
也可以選擇實現 DispatchExceptionHandler
。在這種情況下,DispatcherHandler
會將其應用於在處理器對映之前發生的異常,例如在處理器對映期間,或更早的時候,例如在 WebFilter
中。
檢視解析
檢視解析使得可以使用 HTML 模板和模型向瀏覽器渲染,而無需繫結到特定的檢視技術。在 Spring WebFlux 中,檢視解析透過一個專門的 HandlerResultHandler 支援,該處理器使用 ViewResolver
例項將字串(表示邏輯檢視名)對映到 View
例項。然後使用該 View
來渲染響應。
Web 應用需要使用 檢視渲染庫 來支援此用例。
處理
傳遞給 ViewResolutionResultHandler
的 HandlerResult
包含處理器的返回值以及在請求處理期間添加了屬性的模型。返回值按以下方式之一進行處理
-
String
,CharSequence
: 一個邏輯檢視名,將透過配置的ViewResolver
實現列表解析為View
。 -
void
: 基於請求路徑選擇一個預設檢視名(去除前導和尾部斜槓),並將其解析為View
。當未提供檢視名(例如,返回了模型屬性)或非同步返回值(例如,Mono
完成時為空)時,也會發生同樣的情況。 -
Rendering: 用於檢視解析場景的 API。請在您的 IDE 中透過程式碼補全探索選項。
-
Model
,Map
: 要新增到請求模型的額外模型屬性。 -
任何其他型別:任何其他返回值(簡單型別除外,由 BeanUtils#isSimpleProperty 確定)被視為要新增到模型的模型屬性。屬性名使用 約定 從類名派生,除非存在處理方法上的 `@ModelAttribute` 註解。
模型可以包含非同步的、響應式型別(例如,來自 Reactor 或 RxJava)。在渲染之前,AbstractView
將這些模型屬性解析為具體值並更新模型。單值響應式型別被解析為單個值或無值(如果為空),而多值響應式型別(例如,Flux<T>
)則被收集並解析為 List<T>
。
配置檢視解析就像向您的 Spring 配置中新增一個 ViewResolutionResultHandler
bean 一樣簡單。WebFlux Config 為檢視解析提供了一個專門的配置 API。
有關與 Spring WebFlux 整合的檢視技術的更多資訊,請參閱 檢視技術。
重定向
檢視名中的特殊字首 redirect:
允許您執行重定向。UrlBasedViewResolver
(及其子類)將其識別為需要重定向的指令。檢視名的其餘部分是重定向 URL。
最終效果與控制器返回 RedirectView
或 Rendering.redirectTo(\"abc\").build()
相同,但現在控制器本身可以使用邏輯檢視名進行操作。例如,redirect:/some/resource
檢視名相對於當前應用,而 redirect:https://example.com/arbitrary/path
檢視名則重定向到絕對 URL。
與 Servlet 棧不同,Spring WebFlux 不支援“FORWARD”分派,因此結果不支援 forward: 字首。 |
內容協商
ViewResolutionResultHandler
支援內容協商。它將請求的媒體型別與每個選定 View
支援的媒體型別進行比較。使用第一個支援請求媒體型別(s) 的 View
。
為了支援 JSON 和 XML 等媒體型別,Spring WebFlux 提供了 HttpMessageWriterView
,這是一個特殊的 View
,它透過 HttpMessageWriter 進行渲染。通常,您會透過 WebFlux 配置 將這些配置為預設檢視。如果預設檢視與請求的媒體型別匹配,則總是會被選中並使用。