Spring WebFlux与Spring MVC类似,是围绕前端控制器模式设计的,其中中央WebHandler DispatcherHandler提供了用于请求处理的共享算法,而实际工作是由可配置的委托组件执行的。该模型非常灵活,并支持多种工作流程。
DispatcherHandler从Spring配置中发现所需的委托组件。它还被设计为Spring Bean本身,并实现ApplicationContextAware来访问其运行的上下文。如果以WebHandler的bean名称声明了DispatcherHandler,则WebHttpHandlerBuilder会发现它,而WebHttpHandlerBuilder会将请求处理链组合在一起,如WebHandler API中所述。
WebFlux应用程序中的Spring配置通常包含:
将配置提供给WebHttpHandlerBuilder以构建处理链,如以下示例所示:
ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context);
生成的HttpHandler已准备好与服务器适配器一起使用。
Bean type | Explanation |
---|---|
HandlerMapping | 将请求映射到处理程序。 映射基于某些条件,这些条件的详细信息因HandlerMapping实现而有所不同-带有注解的控制器,简单的URL模式映射以及其他。主要的HandlerMapping实现是用于@RequestMapping注解方法的RequestMappingHandlerMapping,用于功能端点路由的RouterFunctionMapping和用于URI路径模式和WebHandler实例的显式注册的SimpleUrlHandlerMapping。 |
HandlerAdapter | 帮助DispatcherHandler调用映射到请求的处理程序,而不管实际如何调用该处理程序。 例如,调用带注解的控制器需要解析注解。 HandlerAdapter的主要目的是使DispatcherHandler免受此类细节的影响。 |
HandlerResultHandler | 处理来自处理程序调用的结果,并最终确定响应。 请参阅结果处理。 |
应用程序可以声明处理请求所需的基础结构bean(在Web Handler API和DispatcherHandler下列出)。 但是,在大多数情况下,WebFlux Config是最佳起点。 它声明所需的bean,并提供更高级别的配置回调API对其进行自定义。
Spring Boot依靠WebFlux配置来配置Spring WebFlux,并且还提供了许多额外的方便选项。
DispatcherHandler处理请求的方式如下:
通过HandlerAdapter调用处理程序的返回值连同其他一些上下文一起包装为HandlerResult,并传递给第一个支持该处理程序的HandlerResultHandler。 下表显示了可用的HandlerResultHandler实现,所有实现都在WebFlux Config中声明:
Result Handler Type | Return Values | Default Order |
---|---|---|
ResponseEntityResultHandler | ResponseEntity, typically from @Controller instances. | 0 |
ServerResponseResultHandler | ServerResponse, typically from functional endpoints. | 0 |
ResponseBodyResultHandler | Handle return values from @ResponseBody methods or @RestController classes. | 100 |
ViewResolutionResultHandler | CharSequence, View, Model, Map, Rendering, or any other Object is treated as a model attribute. | Integer.MAX_VALUE |
从HandlerAdapter返回的HandlerResult可以公开基于某些特定于处理程序的机制进行错误处理的函数。 在以下情况下将调用此错误函数:
只要在从处理程序返回的反应类型产生任何数据项之前发生错误信号,错误函数就可以更改响应(例如,更改为错误状态)。
这就是支持@Controller类中的@ExceptionHandler方法的方式。 相比之下,Spring MVC中对相同功能的支持建立在HandlerExceptionResolver之上。 这通常不重要。 但是,请记住,在WebFlux中,不能使用@ControllerAdvice来处理在选择处理程序之前发生的异常。
另请参见“带注解的控制器”部分中的“管理异常”或“ WebHandler API”部分中的“异常”。
View Resolution使您可以使用HTML模板和模型渲染到浏览器,而无需将您与特定的视图技术联系在一起。 在Spring WebFlux中,通过专用的HandlerResultHandler支持视图解析,该HandlerResultHandler使用ViewResolver实例将String(表示逻辑视图名称)映射到View实例。 然后使用View呈现响应。
Handling
传递给ViewResolutionResultHandler的HandlerResult包含处理程序的返回值和包含请求处理期间添加的属性的模型。返回值将作为以下值之一进行处理:
该模型可以包含异步,反应式类型(例如,来自Reactor或RxJava)。在渲染之前,AbstractView将此类模型属性解析为具体值并更新模型。单值反应类型被解析为单个值或无值(如果为空),而多值反应类型(例如Flux <T>)被收集并解析为List <T>。
配置视图分辨率就像在Spring配置中添加ViewResolutionResultHandler bean一样简单。 WebFlux Config提供了专用于视图分辨率的配置API。
有关与Spring WebFlux集成的视图技术的更多信息,请参见View Technologies。
Redirecting
视图名称中的特殊redirect:前缀使您可以执行重定向。 UrlBasedViewResolver(和子类)将其识别为需要重定向的指令。 视图名称的其余部分是重定向URL。
最终效果与控制器已返回RedirectView或Rendering.redirectTo(“ abc”)。build()相同,但是现在控制器本身可以根据逻辑视图名称进行操作。 视图名称(例如redirect:/ some / resource)是相对于当前应用程序的,而视图名称(例如redirect:https://example.com/arbitrary/path)将重定向到绝对URL。
Content Negotiation
ViewResolutionResultHandler支持内容协商。 它将请求媒体类型与每个选定视图支持的媒体类型进行比较。 使用支持请求的媒体类型的第一个视图。
为了支持JSON和XML之类的媒体类型,Spring WebFlux提供了HttpMessageWriterView,这是一个通过HttpMessageWriter呈现的特殊视图。 通常,您可以通过WebFlux配置将其配置为默认视图。 如果默认视图与请求的媒体类型匹配,则始终会选择和使用它们。