|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
DispatcherHandler
Spring WebFlux 与 Spring MVC 类似,围绕前端控制器模式进行设计,其中由一个中心 WebHandler(即 DispatcherHandler)提供通用的请求处理算法,而实际工作则由可配置的委托组件来完成。
该模型具有良好的灵活性,能够支持多种工作流程。
DispatcherHandler 从 Spring 配置中发现其所需的委托组件。
它本身也被设计为一个 Spring Bean,并实现了 ApplicationContextAware
以访问其运行所在的上下文。如果 DispatcherHandler 被声明为名为 webHandler 的 Bean,
那么它反过来会被 WebHttpHandlerBuilder 发现,
后者会组装一条请求处理链,正如 WebHandler API 中所述。
WebFlux 应用程序中的 Spring 配置通常包含:
-
DispatcherHandler,其 bean 名称为webHandler -
WebFilter和WebExceptionHandlerBean -
其他
该配置被提供给 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”指的是由 Spring 管理的、实现了 WebFlux 框架契约的 Object 实例。这些 Bean 通常带有内置的契约,但你可以自定义它们的属性、对其进行扩展或替换。
下表列出了由 DispatcherHandler 检测到的特殊 bean。请注意,还有一些其他 bean 在较低层级被检测到(参见 Web Handler API 中的特殊 bean 类型)。
| Bean 类型 | 说明 |
|---|---|
|
将请求映射到一个处理器。该映射基于某些条件,其具体细节因 主要的 |
|
帮助 |
|
处理处理器调用的结果并完成响应。 参见结果处理。 |
WebFlux 配置
应用程序可以声明处理请求所需的基础设施 Bean(列在
Web Handler API 和
DispatcherHandler 下)。
然而,在大多数情况下,WebFlux 配置 是最佳的起点。它声明了所需的 Bean,并提供了更高级别的配置回调 API 以便进行自定义。
| Spring Boot 依赖 WebFlux 配置来设置 Spring WebFlux,并且还提供了许多额外的便捷选项。 |
处理
DispatcherHandler 按如下方式处理请求:
-
每个
HandlerMapping都会被要求查找一个匹配的处理器,第一个匹配的结果将被使用。 -
如果找到了处理器,它将通过一个合适的
HandlerAdapter执行,该适配器会将执行的返回值以HandlerResult的形式暴露出来。 -
HandlerResult会被传递给相应的HandlerResultHandler,以通过直接写入响应或使用视图进行渲染来完成处理。
结果处理
通过 HandlerAdapter 调用处理器所返回的值,会连同一些额外的上下文信息一起被包装为一个 HandlerResult,并传递给第一个声明支持该结果类型的 HandlerResultHandler。下表列出了可用的 HandlerResultHandler 实现,它们均在WebFlux 配置中声明:
| 结果处理器类型 | 返回值 | 默认顺序 |
|---|---|---|
|
|
0 |
|
|
0 |
|
处理来自 |
100 |
|
另请参阅 视图解析。 |
|
异常
HandlerAdapter 的实现可以在内部处理调用请求处理器(例如控制器方法)时产生的异常。然而,如果请求处理器返回一个异步值,则异常可能会被延迟处理。
HandlerAdapter 可以将其异常处理机制作为 DispatchExceptionHandler 暴露出来,并设置在它返回的 HandlerResult 上。当该异常处理器被设置时,DispatcherHandler 也会将其应用于对结果的处理。
HandlerAdapter 也可以选择实现 DispatchExceptionHandler。在这种情况下,DispatcherHandler 会将其应用于在处理器映射之前发生的异常,例如在处理器映射期间,或者更早阶段(例如在 WebFilter 中)发生的异常。
视图解析
视图解析使您能够使用 HTML 模板和模型向浏览器渲染内容,而无需绑定到特定的视图技术。在 Spring WebFlux 中,视图解析通过一个专用的 HandlerResultHandler 来支持,该处理器使用 ViewResolver 实例将一个字符串(代表逻辑视图名称)映射到一个 View 实例。View 随后被用于渲染响应。
处理
传入 HandlerResult 的 ViewResolutionResultHandler 包含处理器的返回值以及在请求处理过程中添加了属性的模型。该返回值将按以下其中一种方式进行处理:
-
String、CharSequence:一个逻辑视图名称,将通过已配置的View实现列表解析为一个ViewResolver。 -
void:根据请求路径(去除开头和结尾的斜杠)选择一个默认视图名称,并将其解析为一个View。当未提供视图名称(例如,返回了模型属性)或异步返回值为空(例如,Mono完成但无内容)时,也会发生同样的情况。 -
渲染:用于视图解析场景的 API。使用 IDE 中的代码补全功能探索可用选项。
-
Model、Map:要为请求添加到模型中的额外模型属性。 -
其他任意类型:任何其他返回值(除了由 BeanUtils#isSimpleProperty 判定的简单类型外)都将被视为模型属性,并添加到模型中。属性名称将根据类名按照约定自动生成,除非处理方法上存在
@ModelAttribute注解。
模型可以包含异步响应式类型(例如来自 Reactor 或 RxJava 的类型)。在渲染之前,AbstractView 会将此类模型属性解析为具体值并更新模型。单值响应式类型会被解析为一个单一值或无值(如果为空),而多值响应式类型(例如 Flux<T>)则会被收集并解析为 List<T>。
配置视图解析非常简单,只需在您的 Spring 配置中添加一个 ViewResolutionResultHandler Bean 即可。WebFlux 配置 提供了专门用于视图解析的配置 API。
有关与 Spring WebFlux 集成的视图技术的更多信息,请参见视图技术。
正在重定向
视图名称中的特殊 redirect: 前缀可让你执行重定向。UrlBasedViewResolver(及其子类)会将此识别为需要执行重定向的指令。视图名称的其余部分即为重定向 URL。
其最终效果与控制器返回 RedirectView 或
Rendering.redirectTo("abc").build() 相同,但现在控制器本身可以使用逻辑视图名称进行操作。像
redirect:/some/resource 这样的视图名称是相对于当前应用程序的,而像
redirect:https://example.com/arbitrary/path 这样的视图名称则会重定向到一个绝对 URL。
内容协商
ViewResolutionResultHandler 支持内容协商。它将请求的媒体类型与每个选定的 View 所支持的媒体类型进行比较。第一个支持所请求媒体类型的 View 将被使用。
为了支持 JSON 和 XML 等媒体类型,Spring WebFlux 提供了 HttpMessageWriterView,这是一种特殊的 View,它通过 HttpMessageWriter 进行渲染。通常,你会通过 WebFlux 配置 将这些视图配置为默认视图。如果默认视图与请求的媒体类型匹配,它们将始终被选中并使用。