DispatcherHandler

Spring WebFlux 与 Spring MVC 类似,设计围绕前端控制器模式,其中一个中央的 WebHandlerDispatcherHandler)提供一个用于请求处理的共享算法,而实际工作由可配置的委托组件执行。此模型很灵活,并且支持各种工作流。 DispatcherHandler 从 Spring 配置中发现它需要的委派组件。它还被设计为 Spring Bean 本身,并实现 ApplicationContextAware,以访问它运行所在的上下文。如果 DispatcherHandler 使用 webHandler 的 Bean 名称声明,则反过来被 WebHttpHandlerBuilder 发现,它会拼凑请求处理链,如 WebHandler API 中所述。 WebFlux 应用程序中的 Spring 配置通常包含:

该配置会提供给 WebHttpHandlerBuilder 以构建处理链,如下面的示例所示:

  • Java

  • Kotlin

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

生成的 HttpHandler 准备与 server adapter 一起使用。

Special Bean Types

DispatcherHandler 委托给特殊 Bean 来处理请求并呈现适当的响应。“特殊 Bean” 指的是实现 WebFlux 框架契约的 Spring 管理 Object 实例。这些通常会附带内置契约,但您可以自定义其属性、对其进行扩展或将其替换。

下表列出了 DispatcherHandler 检测到的特殊 Bean。请注意,还有其他一些 Bean 在较低级别检测到(请参阅 Web 处理器 API 中的 Special bean types)。

Bean type Explanation

HandlerMapping

将请求映射到处理程序。映射基于某些条件,其详细信息因 HandlerMapping 实现而异 - 注解的控制器、简单的 URL 模式映射等等。主要 HandlerMapping 实现,对于用 @RequestMapping 注解的方法,使用 RequestMappingHandlerMapping,对于功能性终结点路由,使用 RouterFunctionMapping,对于 URI 路径模式和 WebHandler 实例的明确注册,使用 SimpleUrlHandlerMapping

HandlerAdapter

无论实际上如何调用处理程序,都帮助 DispatcherHandler 调用映射到请求的处理程序。例如,调用注解的控制器需要解析注解。HandlerAdapter 的主要目的是对 DispatcherHandler 屏蔽此类详细信息。

HandlerResultHandler

处理处理程序调用所得结果并最终确定该响应。参见 Result Handling

WebFlux Config

应用程序可以声明处理请求所需的架构 Bean(在 Web Handler APIDispatcherHandler 下列出)。但是,在大多数情况下,WebFlux Config 是最佳起点。它声明所需的 Bean,并提供高级配置回调 API 来对其进行自定义。

Spring Boot 依赖于 WebFlux 配置来配置 Spring WebFlux,并且还提供了许多额外的便利选项。

Processing

DispatcherHandler 按以下方式处理请求:

  • 要求每个`HandlerMapping`找到一个匹配的处理程序,并使用第一个匹配项。

  • 如果找到处理程序,它将通过适当的`HandlerAdapter`运行,该`HandlerAdapter`将执行的返回值显示为`HandlerResult`。

  • 将`HandlerResult`提供给适当的`HandlerResultHandler`,以通过直接写入响应或使用视图进行渲染,来完成处理。

Result Handling

通过 HandlerAdapter,从处理程序调用的返回值与一些附加上下文一起被包装为 HandlerResult,并传递给第一个声明支持它的 HandlerResultHandler。下表显示了可用的 HandlerResultHandler 实现,所有这些实现都在 WebFlux Config 中声明:

Result Handler Type Return Values Default Order

ResponseEntityResultHandler

通常来自 ResponseEntity 实例。

0

ServerResponseResultHandler

通常来自函数端点。

0

ResponseBodyResultHandler

处理来自 @ResponseBody 方法或 @RestController 类的返回值。

100

ViewResolutionResultHandler

CharSequence、https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/result/view/View.html[View]、https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/ui/Model.html[Model]、Map、https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/result/view/Rendering.html[Rendering] 或任何其他 Object 均被视为模型属性。另请参见 视图解析度

Integer.MAX_VALUE

Exceptions

HandlerAdapter 实现可以内部处理调用请求处理程序(例如控制器方法)引发的异常。但是,如果请求处理程序返回异步值,则可以延迟异常。

HandlerAdapter 可能将其异常处理机制暴露为在其返回的 HandlerResult 上设置的 DispatchExceptionHandler。设置此项后,DispatcherHandler 也将将其应用到结果的处理。

HandlerAdapter 也可能选择实现 DispatchExceptionHandler。在这种情况下,DispatcherHandler 将将其应用于在映射处理程序之前产生的异常,例如在处理程序映射期间,或更早,例如在 WebFilter 中。

另请参阅 “Annotated Controller” 部分中的 Exceptions 或 Web 处理器 API 部分中的 Exceptions

View Resolution

视图解析允许使用 HTML 模板和模型向浏览器呈现,而无需将您绑定到特定的视图技术。在 Spring WebFlux 中,视图解析是通过一个专门的 HandlerResultHandler 支持的,它使用 ViewResolver 实例将字符串(表示逻辑视图名称)映射到 View 实例。然后使用 View 来呈现响应。

Handling

传递给 ViewResolutionResultHandlerHandlerResult 包含处理程序的返回值以及在请求处理过程中添加的属性的模型。返回值按以下方式之一进行处理:

  • StringCharSequence:一个逻辑视图名称,它将通过已配置的`ViewResolver`实现列表解析为`View`。

  • void:根据请求路径(不含前导和尾部斜杠)选择默认视图名称,并将其解析为`View`。视图名称未提供(例如,返回了模型属性)或异步返回值(例如,`Mono`为空)时也会发生相同的情况。

  • Rendering:用于视图解析场景的 API。使用代码自动完成功能在 IDE 中探索选项。

  • ModelMap:要添加到请求模型的额外模型属性。

  • 任何其他内容:任何其他返回值(除了简单类型,如由 BeanUtils#isSimpleProperty 判定)会被视为要添加到模型的模型属性。除非存在处理程序方法`@ModelAttribute`注释,否则属性名称将根据类名通过使用 约定 派生而来。

该模型可以包含异步反应式类型(例如,来自 Reactor 或 RxJava)。在呈现之前,AbstractView 将此类模型属性解析为具体值并更新模型。单值反应式类型解析为单个值或无值(如果为空),而多值反应式类型(例如 Flux<T>)则被收集并解析为 List<T>

要配置视图解析,只需在 Spring 配置中添加一个 @{1} bean。@{2} 提供了一个专门的配置 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 支持内容协商。它将请求媒体类型与各个选定 View 支持的媒体类型进行比较。使用第一个支持所请求媒体类型(s) 的 View

为了支持 JSON 和 XML 等媒体类型,Spring WebFlux 提供了 HttpMessageWriterView,它是一个特殊的 View,通过 HttpMessageWriter 渲染。通常,您会通过 WebFlux Configuration 将这些配置为默认视图。如果默认视图与请求的媒体类型匹配,则始终选择并使用它们。