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 配置 将这些配置为默认视图。如果默认视图与请求的媒体类型匹配,则总是会被选中并使用。