DispatcherHandler
与 Spring MVC 类似,Spring WebFlux 围绕前端控制器模式设计,其中一个中央WebHandler
,即DispatcherHandler
,提供了一个用于请求处理的共享算法,而实际工作则由可配置的委托组件执行。此模型灵活且支持多种工作流。
DispatcherHandler
从 Spring 配置中发现它需要的委托组件。它还被设计为一个 Spring Bean 本身,并实现ApplicationContextAware
以便访问其运行的上下文。如果DispatcherHandler
以webHandler
的 Bean 名称声明,则它又会被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 配置
应用程序可以声明处理请求所需的 Infrastructure Bean(列在Web 处理程序 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
可以将其异常处理机制公开为其返回的HandlerResult
上设置的DispatchExceptionHandler
。当设置了该值时,DispatcherHandler
也将将其应用于结果的处理。
HandlerAdapter
也可以选择实现DispatchExceptionHandler
。在这种情况下,DispatcherHandler
将将其应用于在映射处理程序之前出现的异常,例如,在处理程序映射期间或更早,例如,在WebFilter
中。
视图解析
视图解析允许使用 HTML 模板和模型呈现到浏览器,而无需绑定到特定的视图技术。在 Spring WebFlux 中,视图解析通过专用的HandlerResultHandler 支持,该处理器使用 ViewResolver
实例将字符串(表示逻辑视图名称)映射到 View
实例。然后,使用 View
呈现响应。
Web 应用程序需要使用视图渲染库来支持此用例。
处理
传递到 ViewResolutionResultHandler
的 HandlerResult
包含处理程序的返回值以及包含在请求处理期间添加的属性的模型。返回值将按以下方式之一进行处理
-
String
、CharSequence
:要通过配置的ViewResolver
实现列表解析为View
的逻辑视图名称。 -
void
:根据请求路径(减去开头和结尾的斜杠)选择默认视图名称,并将其解析为View
。当未提供视图名称(例如,返回模型属性)或异步返回值(例如,Mono
完成为空)时,也会发生同样的情况。 -
渲染:视图解析场景的 API。使用代码完成在 IDE 中探索选项。
-
Model
、Map
:要添加到请求模型的其他模型属性。 -
其他任何:任何其他返回值(除了简单类型,由BeanUtils#isSimpleProperty 确定)都被视为要添加到模型的模型属性。属性名称通过使用约定 从类名派生,除非存在处理程序方法
@ModelAttribute
注解。
模型可以包含异步的、反应式的类型(例如,来自 Reactor 或 RxJava)。在渲染之前,AbstractView
将此类模型属性解析为具体值并更新模型。单值反应式类型解析为单个值或无值(如果为空),而多值反应式类型(例如,Flux<T>
)将被收集并解析为 List<T>
。
配置视图解析就像将 ViewResolutionResultHandler
bean 添加到 Spring 配置一样简单。WebFlux 配置 为视图解析提供了专用的配置 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: 前缀作为结果。 |
内容协商
ViewResolutionResultHandler
支持内容协商。它将请求媒体类型与每个选定 View
支持的媒体类型进行比较。使用第一个支持请求媒体类型(s) 的 View
。
为了支持 JSON 和 XML 等媒体类型,Spring WebFlux 提供了 HttpMessageWriterView
,这是一种通过HttpMessageWriter 渲染的特殊 View
。通常,您会通过WebFlux 配置 将它们配置为默认视图。如果默认视图与请求的媒体类型匹配,则始终选择并使用它们。