对于最新稳定版本,请使用 Spring Framework 7.0.6spring-doc.cadn.net.cn

DispatcherHandler

Spring WebFlux 与 Spring MVC 类似,围绕前端控制器模式进行设计,其中由一个中心 WebHandler(即 DispatcherHandler)提供通用的请求处理算法,而实际工作则由可配置的委托组件来完成。 该模型具有良好的灵活性,能够支持多种工作流程。spring-doc.cadn.net.cn

DispatcherHandler 从 Spring 配置中发现其所需的委托组件。 它本身也被设计为一个 Spring Bean,并实现了 ApplicationContextAware 以访问其运行所在的上下文。如果 DispatcherHandler 被声明为名为 webHandler 的 Bean, 那么它反过来会被 WebHttpHandlerBuilder 发现, 后者会组装一条请求处理链,正如 WebHandler API 中所述。spring-doc.cadn.net.cn

WebFlux 应用程序中的 Spring 配置通常包含:spring-doc.cadn.net.cn

该配置被提供给 WebHttpHandlerBuilder 以构建处理链,如下例所示:spring-doc.cadn.net.cn

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

生成的 HttpHandler 已准备好与服务器适配器一起使用。spring-doc.cadn.net.cn

特殊 Bean 类型

DispatcherHandler 将请求委托给特殊的 Bean 进行处理,并渲染相应的响应。这里的“特殊 Bean”指的是由 Spring 管理的、实现了 WebFlux 框架契约的 Object 实例。这些 Bean 通常带有内置的契约,但你可以自定义它们的属性、对其进行扩展或替换。spring-doc.cadn.net.cn

下表列出了由 DispatcherHandler 检测到的特殊 bean。请注意,还有一些其他 bean 在较低层级被检测到(参见 Web Handler API 中的特殊 bean 类型)。spring-doc.cadn.net.cn

Bean 类型 说明

HandlerMappingspring-doc.cadn.net.cn

将请求映射到一个处理器。该映射基于某些条件,其具体细节因 HandlerMapping 实现而异——例如带注解的控制器、简单的 URL 模式映射等。spring-doc.cadn.net.cn

主要的 HandlerMapping 实现包括:用于处理带有 RequestMappingHandlerMapping 注解方法的 @RequestMapping、用于函数式端点路由的 RouterFunctionMapping,以及用于显式注册 URI 路径模式和 SimpleUrlHandlerMapping 实例的 WebHandlerspring-doc.cadn.net.cn

HandlerAdapterspring-doc.cadn.net.cn

帮助 DispatcherHandler 调用映射到请求的处理器,而无需关心处理器实际是如何被调用的。例如,调用一个带注解的控制器需要解析注解。HandlerAdapter 的主要目的是将 DispatcherHandler 与这些细节隔离开来。spring-doc.cadn.net.cn

HandlerResultHandlerspring-doc.cadn.net.cn

处理处理器调用的结果并完成响应。 参见结果处理spring-doc.cadn.net.cn

WebFlux 配置

应用程序可以声明处理请求所需的基础设施 Bean(列在 Web Handler APIDispatcherHandler 下)。 然而,在大多数情况下,WebFlux 配置 是最佳的起点。它声明了所需的 Bean,并提供了更高级别的配置回调 API 以便进行自定义。spring-doc.cadn.net.cn

Spring Boot 依赖 WebFlux 配置来设置 Spring WebFlux,并且还提供了许多额外的便捷选项。

处理

DispatcherHandler 按如下方式处理请求:spring-doc.cadn.net.cn

  • 每个 HandlerMapping 都会被要求查找一个匹配的处理器,第一个匹配的结果将被使用。spring-doc.cadn.net.cn

  • 如果找到了处理器,它将通过一个合适的HandlerAdapter执行,该适配器会将执行的返回值以HandlerResult的形式暴露出来。spring-doc.cadn.net.cn

  • HandlerResult 会被传递给相应的 HandlerResultHandler,以通过直接写入响应或使用视图进行渲染来完成处理。spring-doc.cadn.net.cn

结果处理

通过 HandlerAdapter 调用处理器所返回的值,会连同一些额外的上下文信息一起被包装为一个 HandlerResult,并传递给第一个声明支持该结果类型的 HandlerResultHandler。下表列出了可用的 HandlerResultHandler 实现,它们均在WebFlux 配置中声明:spring-doc.cadn.net.cn

结果处理器类型 返回值 默认顺序

ResponseEntityResultHandlerspring-doc.cadn.net.cn

ResponseEntity,通常来自 @Controller 实例。spring-doc.cadn.net.cn

0spring-doc.cadn.net.cn

ServerResponseResultHandlerspring-doc.cadn.net.cn

ServerResponse,通常来自函数式端点。spring-doc.cadn.net.cn

0spring-doc.cadn.net.cn

ResponseBodyResultHandlerspring-doc.cadn.net.cn

处理来自 @ResponseBody 方法或 @RestController 类的返回值。spring-doc.cadn.net.cn

100spring-doc.cadn.net.cn

ViewResolutionResultHandlerspring-doc.cadn.net.cn

CharSequence, View, 模型, Map, 渲染, 或任何其他 Object 均被视为模型属性。spring-doc.cadn.net.cn

另请参阅 视图解析spring-doc.cadn.net.cn

Integer.MAX_VALUEspring-doc.cadn.net.cn

异常

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

HandlerAdapter 可以将其异常处理机制作为 DispatchExceptionHandler 暴露出来,并设置在它返回的 HandlerResult 上。当该异常处理器被设置时,DispatcherHandler 也会将其应用于对结果的处理。spring-doc.cadn.net.cn

HandlerAdapter 也可以选择实现 DispatchExceptionHandler。在这种情况下,DispatcherHandler 会将其应用于在处理器映射之前发生的异常,例如在处理器映射期间,或者更早阶段(例如在 WebFilter 中)发生的异常。spring-doc.cadn.net.cn

另请参阅“注解控制器”部分中的异常,或 WebHandler API 部分中的异常spring-doc.cadn.net.cn

视图解析

视图解析使您能够使用 HTML 模板和模型向浏览器渲染内容,而无需绑定到特定的视图技术。在 Spring WebFlux 中,视图解析通过一个专用的 HandlerResultHandler 来支持,该处理器使用 ViewResolver 实例将一个字符串(代表逻辑视图名称)映射到一个 View 实例。View 随后被用于渲染响应。spring-doc.cadn.net.cn

处理

传入 HandlerResultViewResolutionResultHandler 包含处理器的返回值以及在请求处理过程中添加了属性的模型。该返回值将按以下其中一种方式进行处理:spring-doc.cadn.net.cn

  • StringCharSequence:一个逻辑视图名称,将通过已配置的 View 实现列表解析为一个 ViewResolverspring-doc.cadn.net.cn

  • void:根据请求路径(去除开头和结尾的斜杠)选择一个默认视图名称,并将其解析为一个 View。当未提供视图名称(例如,返回了模型属性)或异步返回值为空(例如,Mono 完成但无内容)时,也会发生同样的情况。spring-doc.cadn.net.cn

  • 渲染:用于视图解析场景的 API。使用 IDE 中的代码补全功能探索可用选项。spring-doc.cadn.net.cn

  • ModelMap:要为请求添加到模型中的额外模型属性。spring-doc.cadn.net.cn

  • 其他任意类型:任何其他返回值(除了由 BeanUtils#isSimpleProperty 判定的简单类型外)都将被视为模型属性,并添加到模型中。属性名称将根据类名按照约定自动生成,除非处理方法上存在 @ModelAttribute 注解。spring-doc.cadn.net.cn

模型可以包含异步响应式类型(例如来自 Reactor 或 RxJava 的类型)。在渲染之前,AbstractView 会将此类模型属性解析为具体值并更新模型。单值响应式类型会被解析为一个单一值或无值(如果为空),而多值响应式类型(例如 Flux<T>)则会被收集并解析为 List<T>spring-doc.cadn.net.cn

配置视图解析非常简单,只需在您的 Spring 配置中添加一个 ViewResolutionResultHandler Bean 即可。WebFlux 配置 提供了专门用于视图解析的配置 API。spring-doc.cadn.net.cn

有关与 Spring WebFlux 集成的视图技术的更多信息,请参见视图技术spring-doc.cadn.net.cn

正在重定向

视图名称中的特殊 redirect: 前缀可让你执行重定向。UrlBasedViewResolver(及其子类)会将此识别为需要执行重定向的指令。视图名称的其余部分即为重定向 URL。spring-doc.cadn.net.cn

其最终效果与控制器返回 RedirectViewRendering.redirectTo("abc").build() 相同,但现在控制器本身可以使用逻辑视图名称进行操作。像 redirect:/some/resource 这样的视图名称是相对于当前应用程序的,而像 redirect:https://example.com/arbitrary/path 这样的视图名称则会重定向到一个绝对 URL。spring-doc.cadn.net.cn

内容协商

ViewResolutionResultHandler 支持内容协商。它将请求的媒体类型与每个选定的 View 所支持的媒体类型进行比较。第一个支持所请求媒体类型的 View 将被使用。spring-doc.cadn.net.cn

为了支持 JSON 和 XML 等媒体类型,Spring WebFlux 提供了 HttpMessageWriterView,这是一种特殊的 View,它通过 HttpMessageWriter 进行渲染。通常,你会通过 WebFlux 配置 将这些视图配置为默认视图。如果默认视图与请求的媒体类型匹配,它们将始终被选中并使用。spring-doc.cadn.net.cn