DispatcherHandler
Spring WebFlux 与 Spring MVC 类似,设计围绕前端控制器模式,其中一个中央的 WebHandler
(DispatcherHandler
)提供一个用于请求处理的共享算法,而实际工作由可配置的委托组件执行。此模型很灵活,并且支持各种工作流。
Spring WebFlux, similarly to Spring MVC, is designed around the front controller pattern,
where a central WebHandler
, the DispatcherHandler
, provides a shared algorithm for
request processing, while actual work is performed by configurable, delegate components.
This model is flexible and supports diverse workflows.
DispatcherHandler
从 Spring 配置中发现它需要的委派组件。它还被设计为 Spring Bean 本身,并实现 ApplicationContextAware
,以访问它运行所在的上下文。如果 DispatcherHandler
使用 webHandler
的 Bean 名称声明,则反过来被 WebHttpHandlerBuilder
发现,它会拼凑请求处理链,如 WebHandler
API 中所述。
DispatcherHandler
discovers the delegate components it needs from Spring configuration.
It is also designed to be a Spring bean itself and implements ApplicationContextAware
for access to the context in which it runs. If DispatcherHandler
is declared with a bean
name of webHandler
, it is, in turn, discovered by
WebHttpHandlerBuilder
,
which puts together a request-processing chain, as described in WebHandler
API.
WebFlux 应用程序中的 Spring 配置通常包含:
Spring configuration in a WebFlux application typically contains:
-
DispatcherHandler
with the bean namewebHandler
-
WebFilter
andWebExceptionHandler
beans -
Others
该配置会提供给 WebHttpHandlerBuilder
以构建处理链,如下面的示例所示:
The configuration is given to WebHttpHandlerBuilder
to build the processing chain,
as the following example shows:
-
Java
-
Kotlin
ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context).build();
val context: ApplicationContext = ...
val handler = WebHttpHandlerBuilder.applicationContext(context).build()
生成的 HttpHandler
准备与 server adapter 一起使用。
The resulting HttpHandler
is ready for use with a server adapter.
Special Bean Types
DispatcherHandler
委托给特殊 Bean 来处理请求并呈现适当的响应。“特殊 Bean” 指的是实现 WebFlux 框架契约的 Spring 管理 Object
实例。这些通常会附带内置契约,但您可以自定义其属性、对其进行扩展或将其替换。
The DispatcherHandler
delegates to special beans to process requests and render the
appropriate responses. By “special beans,” we mean Spring-managed Object
instances that
implement WebFlux framework contracts. Those usually come with built-in contracts, but
you can customize their properties, extend them, or replace them.
下表列出了 DispatcherHandler
检测到的特殊 Bean。请注意,还有其他一些 Bean 在较低级别检测到(请参阅 Web 处理器 API 中的 Special bean types)。
The following table lists the special beans detected by the DispatcherHandler
. Note that
there are also some other beans detected at a lower level (see
Special bean types in the Web Handler API).
Bean type | Explanation |
---|---|
|
Map a request to a handler. The mapping is based on some criteria, the details of
which vary by The main |
|
Help the |
|
Process the result from the handler invocation and finalize the response. See Result Handling. |
WebFlux Config
应用程序可以声明处理请求所需的架构 Bean(在 Web Handler API 和 DispatcherHandler
下列出)。但是,在大多数情况下,WebFlux Config 是最佳起点。它声明所需的 Bean,并提供高级配置回调 API 来对其进行自定义。
Applications can declare the infrastructure beans (listed under
Web Handler API and
DispatcherHandler
) that are required to process requests.
However, in most cases, the WebFlux Config is the best starting point. It declares the
required beans and provides a higher-level configuration callback API to customize it.
Spring Boot 依赖于 WebFlux 配置来配置 Spring WebFlux,并且还提供了许多额外的便利选项。 |
Spring Boot relies on the WebFlux config to configure Spring WebFlux and also provides many extra convenient options. |
Processing
DispatcherHandler
按以下方式处理请求:
DispatcherHandler
processes requests as follows:
-
Each
HandlerMapping
is asked to find a matching handler, and the first match is used. -
If a handler is found, it is run through an appropriate
HandlerAdapter
, which exposes the return value from the execution asHandlerResult
. -
The
HandlerResult
is given to an appropriateHandlerResultHandler
to complete processing by writing to the response directly or by using a view to render.
Result Handling
通过 HandlerAdapter
,从处理程序调用的返回值与一些附加上下文一起被包装为 HandlerResult
,并传递给第一个声明支持它的 HandlerResultHandler
。下表显示了可用的 HandlerResultHandler
实现,所有这些实现都在 WebFlux Config 中声明:
The return value from the invocation of a handler, through a HandlerAdapter
, is wrapped
as a HandlerResult
, along with some additional context, and passed to the first
HandlerResultHandler
that claims support for it. The following table shows the available
HandlerResultHandler
implementations, all of which are declared in the WebFlux Config:
Result Handler Type | Return Values | Default Order |
---|---|---|
|
|
0 |
|
|
0 |
|
Handle return values from |
100 |
|
See also View Resolution. |
|
Exceptions
HandlerAdapter
实现可以内部处理调用请求处理程序(例如控制器方法)引发的异常。但是,如果请求处理程序返回异步值,则可以延迟异常。
HandlerAdapter
implementations can handle internally exceptions from invoking a request
handler, such as a controller method. However, an exception may be deferred if the request
handler returns an asynchronous value.
HandlerAdapter
可能将其异常处理机制暴露为在其返回的 HandlerResult
上设置的 DispatchExceptionHandler
。设置此项后,DispatcherHandler
也将将其应用到结果的处理。
A HandlerAdapter
may expose its exception handling mechanism as a
DispatchExceptionHandler
set on the HandlerResult
it returns. When that’s set,
DispatcherHandler
will also apply it to the handling of the result.
HandlerAdapter
也可能选择实现 DispatchExceptionHandler
。在这种情况下,DispatcherHandler
将将其应用于在映射处理程序之前产生的异常,例如在处理程序映射期间,或更早,例如在 WebFilter
中。
A HandlerAdapter
may also choose to implement DispatchExceptionHandler
. In that case
DispatcherHandler
will apply it to exceptions that arise before a handler is mapped,
e.g. during handler mapping, or earlier, e.g. in a WebFilter
.
另请参阅 “Annotated Controller” 部分中的 Exceptions 或 Web 处理器 API 部分中的 Exceptions。
See also Exceptions in the “Annotated Controller” section or Exceptions in the WebHandler API section.
View Resolution
视图解析允许使用 HTML 模板和模型向浏览器呈现,而无需将您绑定到特定的视图技术。在 Spring WebFlux 中,视图解析是通过一个专门的 HandlerResultHandler 支持的,它使用 ViewResolver
实例将字符串(表示逻辑视图名称)映射到 View
实例。然后使用 View
来呈现响应。
View resolution enables rendering to a browser with an HTML template and a model without
tying you to a specific view technology. In Spring WebFlux, view resolution is
supported through a dedicated HandlerResultHandler that uses
ViewResolver
instances to map a String (representing a logical view name) to a View
instance. The View
is then used to render the response.
Handling
传递给 ViewResolutionResultHandler
的 HandlerResult
包含处理程序的返回值以及在请求处理过程中添加的属性的模型。返回值按以下方式之一进行处理:
The HandlerResult
passed into ViewResolutionResultHandler
contains the return value
from the handler and the model that contains attributes added during request
handling. The return value is processed as one of the following:
-
String
,CharSequence
: A logical view name to be resolved to aView
through the list of configuredViewResolver
implementations. -
void
: Select a default view name based on the request path, minus the leading and trailing slash, and resolve it to aView
. The same also happens when a view name was not provided (for example, model attribute was returned) or an async return value (for example,Mono
completed empty). -
Rendering: API for view resolution scenarios. Explore the options in your IDE with code completion.
-
Model
,Map
: Extra model attributes to be added to the model for the request. -
Any other: Any other return value (except for simple types, as determined by BeanUtils#isSimpleProperty) is treated as a model attribute to be added to the model. The attribute name is derived from the class name by using conventions, unless a handler method
@ModelAttribute
annotation is present.
该模型可以包含异步反应式类型(例如,来自 Reactor 或 RxJava)。在呈现之前,AbstractView
将此类模型属性解析为具体值并更新模型。单值反应式类型解析为单个值或无值(如果为空),而多值反应式类型(例如 Flux<T>
)则被收集并解析为 List<T>
。
The model can contain asynchronous, reactive types (for example, from Reactor or RxJava). Prior
to rendering, AbstractView
resolves such model attributes into concrete values
and updates the model. Single-value reactive types are resolved to a single
value or no value (if empty), while multi-value reactive types (for example, Flux<T>
) are
collected and resolved to List<T>
.
要配置视图解析,只需在 Spring 配置中添加一个 @{1} bean。@{2} 提供了一个专门的配置 API,用于视图解析。
To configure view resolution is as simple as adding a ViewResolutionResultHandler
bean
to your Spring configuration. WebFlux Config provides a
dedicated configuration API for view resolution.
有关与 Spring WebFlux 集成的视图技术的更多信息,请参阅 View Technologies。
See View Technologies for more on the view technologies integrated with Spring WebFlux.
Redirecting
视图名称中的特殊 redirect:
前缀允许您执行重定向。UrlBasedViewResolver
(以及子类)将其识别为重定向所需的指示。视图名称的其余部分是重定向 URL。
The special redirect:
prefix in a view name lets you perform a redirect. The
UrlBasedViewResolver
(and sub-classes) recognize this as an instruction that a
redirect is needed. The rest of the view name is the redirect URL.
最终效果与控制器返回 RedirectView
或`Rendering.redirectTo("abc").build()` 相同,但现在控制器本身可以使用逻辑视图名称进行操作。视图名称(如`redirect:/some/resource`)相对于当前应用程序,而视图名称(如`redirect:https://example.com/arbitrary/path`)重定向到绝对 URL。
The net effect is the same as if the controller had returned a RedirectView
or
Rendering.redirectTo("abc").build()
, but now the controller itself can
operate in terms of logical view names. A view name such as
redirect:/some/resource
is relative to the current application, while a view name such as
redirect:https://example.com/arbitrary/path
redirects to an absolute URL.
Content Negotiation
ViewResolutionResultHandler
支持内容协商。它将请求媒体类型与各个选定 View
支持的媒体类型进行比较。使用第一个支持所请求媒体类型(s) 的 View
。
ViewResolutionResultHandler
supports content negotiation. It compares the request
media types with the media types supported by each selected View
. The first View
that supports the requested media type(s) is used.
为了支持 JSON 和 XML 等媒体类型,Spring WebFlux 提供了 HttpMessageWriterView
,它是一个特殊的 View
,通过 HttpMessageWriter 渲染。通常,您会通过 WebFlux Configuration 将这些配置为默认视图。如果默认视图与请求的媒体类型匹配,则始终选择并使用它们。
In order to support media types such as JSON and XML, Spring WebFlux provides
HttpMessageWriterView
, which is a special View
that renders through an
HttpMessageWriter. Typically, you would configure these as default
views through the WebFlux Configuration. Default views are
always selected and used if they match the requested media type.