跳到主要内容
版本:7.0.3

DispatcherHandler

Hunyuan 7b 中英对照 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”指的是由 Spring 管理的、实现了 WebFlux 框架契约的 Object 实例。这些 Bean 通常自带内置的契约,但你可以自定义它们的属性、扩展它们,或者替换它们。

下表列出了由DispatcherHandler检测到的特殊Bean。请注意,还有其他一些Bean在更低的层级也被检测到(详见Web处理程序API中的特殊Bean类型)。

Bean 类型说明
HandlerMapping将请求映射到处理器(handler)。这种映射基于某些标准,具体细节因 HandlerMapping 的实现而异——例如带有注解的控制器、简单的 URL 模式映射等。

主要的 HandlerMapping 实现包括:用于带有 @RequestMapping 注解的方法的 RequestMappingHandlerMapping,用于函数端点路由的 RouterFunctionMapping,以及用于显式注册 URI 路径模式和 WebHandler 实例的 SimpleUrlHandlerMapping
HandlerAdapter帮助 DispatcherHandler 调用与请求匹配的处理器,而不关心处理器的实际调用方式。例如,调用带有注解的控制器需要解析这些注解。HandlerAdapter 的主要作用就是让 DispatcherHandler 不必关注这些细节。
HandlerResultHandler处理处理器调用的结果,并完成响应的生成。详见 结果处理

WebFlux 配置

应用程序可以声明处理请求所需的基础设施bean(列在Web Handler APIDispatcherHandler下)。然而,在大多数情况下,WebFlux Config是更好的起点。它声明了所需的bean,并提供了一个更高级别的配置回调API来进行定制。

备注

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

处理

DispatcherHandler 按以下方式处理请求:

  • 每个 HandlerMapping 都会被要求找到一个匹配的处理程序(handler),并使用第一个匹配的结果。
  • 如果找到了处理程序,它将通过一个合适的 HandlerAdapter 运行,该适配器会将执行结果以 HandlerResult 的形式返回。
  • HandlerResult 会被传递给一个合适的 HandlerResultHandler,后者通过直接写入响应或使用视图来渲染来完成后续处理。

结果处理

通过HandlerAdapter调用处理器(handler)后返回的值会被封装成HandlerResult对象,其中还包含一些额外的上下文信息,然后传递给第一个支持该HandlerResultHandlerResultHandler。下表列出了可用的HandlerResultHandler实现,这些实现都在WebFlux Config中进行了声明:

结果处理器类型返回值默认顺序
ResponseEntityResultHandlerResponseEntity,通常来自@Controller实例。0
ServerResponseResultHandlerServerResponse,通常来自函数式端点。0
ResponseBodyResultHandler处理来自@ResponseBody方法或@RestController类的返回值。100
ViewResolutionResultHandlerCharSequenceViewModelMapRendering,或任何其他Object均被视为模型属性。

另请参阅视图解析
Integer.MAX_VALUE

异常

HandlerAdapter的实现可以内部处理调用请求处理器(如控制器方法)时产生的异常。但是,如果请求处理器返回的是异步值,那么该异常可能会被延迟处理。

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

HandlerAdapter也可以选择实现DispatchExceptionHandler。在这种情况下,DispatchHandler会将其应用于在处理程序映射之前发生的异常,例如,在处理程序映射过程中,或者更早的阶段,例如在WebFilter中。

另请参阅“带注释的控制器”部分中的异常处理,或WebHandler API部分中的异常处理

视图分辨率

视图解析功能能够将HTML模板和模型渲染到浏览器中,而不会让您局限于特定的视图技术。在Spring WebFlux中,视图解析是通过一个专门的HandlerResultHandler来支持的,该处理器使用ViewResolver实例将一个字符串(代表逻辑视图名称)映射到一个View实例上。然后使用这个View来生成响应内容。

Web应用程序需要使用视图渲染库来支持这种用例。

处理

[参见Servlet堆栈中的等效实现](../webmvc/mvc-servlet/view Resolver.md#mvc-view-resolver-handling)

传递给ViewResolutionResultHandlerHandlerResult包含了处理器的返回值,以及在该请求处理过程中添加了属性的模型。返回值将按照以下方式之一进行处理:

  • String, CharSequence: 一个逻辑视图名称,通过已配置的 ViewResolver 实现列表解析为 View

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

  • Rendering: 视图解析场景的 API。您可以在 IDE 中使用代码完成功能来探索这些选项。

  • Model, Map: 要添加到请求模型的额外模型属性。

  • 任何其他返回值:除简单类型外(由 BeanUtils#isSimpleProperty 决定),任何其他返回值都会被视为要添加到模型中的模型属性。属性名称是根据类名使用 约定 得出的,除非存在 @ModelAttribute 注解的处理方法。

该模型可以包含异步、反应式的类型(例如,来自Reactor或RxJava的类型)。在渲染之前,AbstractView会将这些模型属性解析为具体的值,并更新模型。单值反应式类型会被解析为一个具体的值,或者如果没有值则解析为无值;而多值反应式类型(例如Flux<T>)则会被收集起来并解析为List<T>

要配置视图解析,只需在Spring配置中添加一个ViewResolutionResultHandlerbean即可。WebFlux Config提供了专门的配置API用于视图解析。

有关与 Spring WebFlux 集成的视图技术的更多信息,请参阅 View Technologies

重定向

在视图名称中,特殊的 redirect: 前缀允许你执行重定向。UrlBasedViewResolver(及其子类)会将此识别为需要执行重定向的指令。视图名称的其余部分就是重定向的URL。

净效果就如同控制器返回了一个RedirectViewRendering.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 Configuration来配置这些作为默认视图。如果默认视图与请求的媒体类型匹配,那么就会始终选择并使用这些默认视图。