DispatcherHandler
Spring WebFlux 与 Spring MVC 类似,设计围绕前端控制器模式,其中一个中央的 WebHandler
(DispatcherHandler
)提供一个用于请求处理的共享算法,而实际工作由可配置的委托组件执行。此模型很灵活,并且支持各种工作流。
DispatcherHandler
从 Spring 配置中发现它需要的委派组件。它还被设计为 Spring Bean 本身,并实现 ApplicationContextAware
,以访问它运行所在的上下文。如果 DispatcherHandler
使用 webHandler
的 Bean 名称声明,则反过来被 WebHttpHandlerBuilder
发现,它会拼凑请求处理链,如 WebHandler
API 中所述。
WebFlux 应用程序中的 Spring 配置通常包含:
-
使用 bean 名称 `webHandler`对`DispatcherHandler`进行注释
-
WebFilter
andWebExceptionHandler
beans -
Others
该配置会提供给 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 |
---|---|
|
将请求映射到处理程序。映射基于某些条件,其详细信息因 |
|
无论实际上如何调用处理程序,都帮助 |
|
处理处理程序调用所得结果并最终确定该响应。参见 Result Handling。 |
WebFlux Config
应用程序可以声明处理请求所需的架构 Bean(在 Web Handler API 和 DispatcherHandler
下列出)。但是,在大多数情况下,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 |
---|---|---|
|
通常来自 |
0 |
|
通常来自函数端点。 |
0 |
|
处理来自 |
100 |
|
|
|
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
传递给 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 配置中添加一个 @{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 将这些配置为默认视图。如果默认视图与请求的媒体类型匹配,则始终选择并使用它们。