跳到主要内容
版本:6.2.3

DispatcherHandler

ChatGPT-4o 中英对照 DispatcherHandler DispatcherHandler

Spring WebFlux 与 Spring MVC 类似,是围绕前端控制器模式设计的,其中一个中心 WebHandler,即 DispatcherHandler,提供了一个共享的请求处理算法,而实际的工作则由可配置的委托组件执行。这个模型灵活且支持多样化的工作流程。

DispatcherHandler 从 Spring 配置中发现其所需的委托组件。它也被设计为一个 Spring bean 本身,并实现了 ApplicationContextAware 接口以访问其运行的上下文。如果 DispatcherHandler 被声明为一个名为 webHandler 的 bean,那么 WebHttpHandlerBuilder 将会发现它,并如 WebHandler API 中所述,组装一个请求处理链。

在 WebFlux 应用程序中的 Spring 配置通常包含:

配置被提供给 WebHttpHandlerBuilder 以构建处理链,如下例所示:

ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context).build();

生成的 HttpHandler 已准备好与服务器适配器一起使用。

特殊 Bean 类型​

DispatcherHandler 委托给特殊的 bean 来处理请求并渲染适当的响应。所谓“特殊的 bean”,是指实现 WebFlux 框架契约的 Spring 管理的 Object 实例。这些通常带有内置契约,但您可以自定义其属性、扩展或替换它们。

下表列出了 DispatcherHandler 检测到的特殊 bean。请注意,还有一些其他 bean 在更低级别被检测到(请参阅 Web Handler API 中的特殊 bean 类型)。

Bean 类型解释
HandlerMapping将请求映射到处理器。映射基于某些标准,其详细信息因 HandlerMapping 实现而异 — 注解控制器、简单的 URL 模式映射等。

主要的 HandlerMapping 实现有用于 @RequestMapping 注解方法的 RequestMappingHandlerMapping,用于功能性端点路由的 RouterFunctionMapping,以及用于显式注册 URI 路径模式和 WebHandler 实例的 SimpleUrlHandlerMapping。
HandlerAdapter帮助 DispatcherHandler 调用映射到请求的处理器,而不管处理器实际上是如何调用的。例如,调用注解控制器需要解析注解。HandlerAdapter 的主要目的是使 DispatcherHandler 不受这些细节的影响。
HandlerResultHandler处理处理器调用的结果并完成响应。参见结果处理。

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 配置 中声明:

结果处理器类型返回值默认顺序
ResponseEntityResultHandlerResponseEntity,通常来自 @Controller 实例。0
ServerResponseResultHandlerServerResponse,通常来自功能性端点。0
ResponseBodyResultHandler处理来自 @ResponseBody 方法或 @RestController 类的返回值。100
ViewResolutionResultHandlerCharSequence、View、Model、Map、Rendering 或任何其他 Object 被视为模型属性。

另请参见 视图解析。
Integer.MAX_VALUE

异常​

HandlerAdapter 实现可以在内部处理调用请求处理器(例如控制器方法)时产生的异常。然而,如果请求处理器返回一个异步值,异常可能会被延迟处理。

一个 HandlerAdapter 可以将其异常处理机制作为 DispatchExceptionHandler 暴露,并设置在它返回的 HandlerResult 上。当设置了这个时,DispatcherHandler 也会将其应用于结果的处理。

一个 HandlerAdapter 也可以选择实现 DispatchExceptionHandler。在这种情况下,DispatcherHandler 会将其应用于在处理程序映射之前出现的异常,例如,在处理程序映射期间,或者更早,例如,在 WebFilter 中。

另请参阅“注解控制器”部分中的异常或 WebHandler API 部分中的异常。

视图解析​

视图解析允许使用 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 配置 提供了一个专用的视图解析配置 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 支持的媒体类型进行比较。第一个支持请求的媒体类型的 View 将被使用。

为了支持 JSON 和 XML 等媒体类型,Spring WebFlux 提供了 HttpMessageWriterView,这是一种通过 HttpMessageWriter 渲染的特殊 View。通常,你可以通过 WebFlux 配置 将这些配置为默认视图。如果默认视图与请求的媒体类型匹配,则总是会被选择和使用。