Spring WebFlux核心處理組件DispatcherHandler
概述
?與Spring MVC類似,Spring WebFlux是圍繞前端控制器模式設(shè)計的,其中核心處理程序WebHandler 的實現(xiàn)DispatcherHandler為請求處理提供共享算法,而實際工作由可配置的委托組件執(zhí)行。該模型非常靈活,支持多種工作流。
DispatcherHandler從Spring配置中發(fā)現(xiàn)所需的委托組件。它本身也被設(shè)計為bean,并實現(xiàn)ApplicationContextAware以訪問它運行的上下文。如果DispatcherHandler是用webHandler的bean名稱聲明的,那么WebHttpHandlerBuilder會發(fā)現(xiàn)它,它會將請求處理鏈組合在一起,如webHandler API中所述。
WebFlux應(yīng)用程序中的Spring配置通常包含:
- bean名稱為webHandler的DispatcherHandler
- WebFilter和WebExceptionHandler
- DispatcherHandler特殊bean
- 其它
配置被提供給WebHttpHandlerBuilder以構(gòu)建處理鏈,如下例所示:
特殊一樣的Bean
?DispatcherHandler委托特殊bean處理請求并呈現(xiàn)適當?shù)捻憫?yīng)。所謂“特殊bean”,是指實現(xiàn)WebFlux框架規(guī)定的Spring管理的對象實例。一般都內(nèi)置這些Bean,不過你可以自定義、擴展或替換它們的屬性。
- HandlerMapping
將請求映射到處理程序。映射基于一些標準,這些標準的細節(jié)因HandlerMapping實現(xiàn)的不同而不同——注釋控制器、簡單URL模式映射等等。如:@RequestMapping注解的Controller或RouterFunction類型的Bean他們都是由不同的HandlerMapping來處理。
- HandlerAdapter
幫助DispatcherHandler調(diào)用映射到請求的處理程序,而不管該處理程序?qū)嶋H是如何調(diào)用的。例如,調(diào)用帶注釋的控制器需要解析注釋。HandlerAdapter的主要目的是保護DispatcherHandler不受這些細節(jié)的影響。簡單說就是不同的HandlerAdapter處理由不同HandlerMapping返回的不同的Handler對象,比如:RequestMappingHandlerMapping返回的HandlerMethod,RouterFunctionMapping返回的HandlerFunction。
- HandlerResultHandler?
處理處理程序調(diào)用的結(jié)果并完成響應(yīng)。
WebFlux配置
應(yīng)用程序可以聲明處理請求所需的基礎(chǔ)bean(列在Web Handler API和DispatcherHandler下面)。但是,在大多數(shù)情況下,WebFlux配置是最好的起點。它聲明所需的bean,并提供更高級別的配置回調(diào)API來自定義它。
請求處理
DispatcherHandler處理請求的方式如下:
- 每個HandlerMapping被要求找到一個匹配的處理程序,并使用第一個匹配。
- 如果找到處理程序,則通過適當?shù)?span style="color: #f04142;">HandlerAdapter運行它,它將從執(zhí)行中返回的值公開為HandlerResult。
- HandlerResult被提供給適當?shù)?span style="color: #f04142;">HandlerResultHandler,以通過直接寫入響應(yīng)或使用視圖進行渲染來完成處理。
結(jié)果處理
調(diào)用處理程序的返回值通過HandlerAdapter被包裝為HandlerResult,以及一些附加的上下文,并傳遞給聲稱支持它的第一個HandlerResultHandler。下表列出可用的HandlerResultHandler實現(xiàn),所有這些實現(xiàn)都在WebFlux Config中聲明:
- ResponseEntityResultHandler
返回值:ResponseEntity, 通常來自@Controller實例。
- ServerResponseResultHandler
返回值:ServerResponse,通常來自功能端點。
- ResponseBodyResultHandler
返回值:處理來自@ResponseBody方法或@RestController類的返回值。
- ViewResolutionResultHandler?
返回值:CharSequence、視圖、模型、映射、渲染或任何其他對象都被視為模型屬性。
異常處理
從HandlerAdapter返回的HandlerResult可以基于某些特定于處理程序的機制公開用于錯誤處理的函數(shù)。在以下情況下調(diào)用此錯誤函數(shù):
- 處理程序(例如,@Controller)調(diào)用失敗。
- 通過HandlerResultHandler處理處理程序返回值失敗。
只要錯誤信號發(fā)生在從處理程序返回的響應(yīng)類型產(chǎn)生任何數(shù)據(jù)項之前,error函數(shù)就可以更改響應(yīng)(例如,更改為錯誤狀態(tài))。
這就是如何支持@Controller類中的@ExceptionHandler方法。相比之下,Spring MVC中的支持也是建立在HandlerExceptionResolver上的。注意:在WebFlux中,不能使用@ControllerAdvice來處理在選擇處理程序之前發(fā)生的異常。?
注意:這個不能處理調(diào)用處理程序之前的任何異常,處理程序之前的異常應(yīng)該由WebExceptionHandler來處理
下面的異常處理句柄將會處理,由WebFilter實例鏈和目標WebHandle的異常。