DispatcherHandler
Spring WebFlux 与 Spring MVC 类似,围绕前端控制器模式设计,其中一个中央 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 处理程序 API 中的 特殊 bean 类型)。
Bean 类型 | 说明 |
---|---|
|
将请求映射到处理程序。映射基于某些条件,具体细节因 主要的 |
|
帮助 |
|
处理处理程序调用的结果并完成响应。请参阅 结果处理。 |
WebFlux 配置
应用程序可以声明处理请求所需的(在 Web 处理程序 API 和 DispatcherHandler
下列出的)基础设施 bean。但是,在大多数情况下,WebFlux 配置 是最佳起点。它声明所需的 bean,并提供更高级别的配置回调 API 来对其进行自定义。
Spring Boot 依赖于 WebFlux 配置来配置 Spring WebFlux,还提供了许多额外的便捷选项。 |
处理
DispatcherHandler
如下处理请求
-
要求每个
HandlerMapping
查找匹配的处理程序,并使用第一个匹配项。 -
如果找到处理程序,则通过适当的
HandlerAdapter
运行它,该HandlerAdapter
将执行的返回值作为HandlerResult
公开。 -
HandlerResult
交给适当的HandlerResultHandler
,通过直接写入响应或使用视图进行渲染来完成处理。
结果处理
通过 HandlerAdapter
调用处理程序的返回值作为 HandlerResult
封装,并附带一些其他上下文,然后传递给第一个声明支持它的 HandlerResultHandler
。下表显示了可用的 HandlerResultHandler
实现,所有这些实现都在 WebFlux 配置 中声明
结果处理程序类型 | 返回值 | 默认顺序 |
---|---|---|
|
|
0 |
|
|
0 |
|
处理 |
100 |
|
另请参见 视图解析。 |
|
异常
HandlerAdapter
实现可以内部处理调用请求处理程序(例如控制器方法)的异常。但是,如果请求处理程序返回异步值,则可能会延迟异常。
HandlerAdapter
可以将其异常处理机制公开为在其返回的 HandlerResult
上设置的 DispatchExceptionHandler
。设置后,DispatcherHandler
也会将其应用于结果的处理。
HandlerAdapter
也可以选择实现 DispatchExceptionHandler
。在这种情况下,DispatcherHandler
会将其应用于在映射处理程序之前出现的异常,例如在处理程序映射期间或更早,例如在 WebFilter
中。
视图解析
视图解析支持使用 HTML 模板和模型向浏览器渲染,而无需将您绑定到特定的视图技术。在 Spring WebFlux 中,视图解析通过一个专门的 HandlerResultHandler 来支持,该 HandlerResultHandler 使用 `ViewResolver` 实例将一个字符串(表示逻辑视图名称)映射到一个 `View` 实例。然后使用 `View` 来渲染响应。
处理
传递到 `ViewResolutionResultHandler` 中的 `HandlerResult` 包含从处理程序返回的值和在请求处理期间添加的属性的模型。返回值将被处理为以下之一
-
String
、CharSequence
:一个逻辑视图名称,将通过已配置的 `ViewResolver` 实现列表解析为 `View`。 -
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 配置 将这些配置为默认视图。如果默认视图与所请求的媒体类型匹配,则始终选择并使用它们。