Reactive Web Applications
Spring Boot 通过为 Spring Webflux 提供自动配置来简化响应式 Web 应用程序的开发。
The “Spring WebFlux Framework”
Spring WebFlux 是 Spring Framework 5.0 中引入的新的响应式 Web 框架。与 Spring MVC 不同,它不需要 servlet API,是完全异步和非阻塞的,并通过 the Reactor project实现 Reactive Streams规范。
Spring WebFlux 有两种模式:基于函数和基于注解。基于注解的模式非常接近 Spring MVC 模型,如下例所示:
WebFlux 是 Spring Framework 的一部分,其详细信息可在 {url-spring-framework-docs}/web/webflux.html[参考文档] 中找到。
“WebFlux.fn”,函数变体将路由配置与请求的实际处理分离开来,如下例所示:
"`WebFlux.fn`"是 Spring Framework 的一部分,其详细信息可在 {url-spring-framework-docs}/web/webflux-functional.html[参考文档] 中找到。
你可以根据需要定义任意数量的 `RouterFunction`bean 来模块化路由器的定义。如果需要应用优先级,可以对 bean 进行排序。 |
要开始使用,请将 `spring-boot-starter-webflux`模块添加到应用程序。
在应用程序中同时添加 |
Spring WebFlux Auto-configuration
Spring Boot 为 Spring WebFlux 提供自动配置,适用于大多数应用程序。
自动配置在 Spring 默认配置之上添加了以下功能:
-
为 `HttpMessageReader`和 `HttpMessageWriter`实例配置编解码器(已在 later in this document中描述)。
-
支持提供静态资源,包括对 WebJar 的支持(已在 later in this document中描述)。
如果您想保留 Spring Boot WebFlux 功能并且想添加其他 {url-spring-framework-docs}/web/webflux/config.html[WebFlux 配置],您可以添加自己的 @Configuration`类,类型为 `WebFluxConfigurer`但 without `@EnableWebFlux
。
如果您想对自动配置的 HttpHandler`进行其他自定义,可以定义 `WebHttpHandlerBuilderCustomizer`类型的 bean 并使用它们修改 `WebHttpHandlerBuilder
。
如果您想完全控制 Spring WebFlux,那么您可以添加您自己的 @Configuration
,带 `@EnableWebFlux`注释。
Spring WebFlux Conversion Service
如果你要自定义 Spring WebFlux 用到的 ConversionService
,你可以提供一个带有 addFormatters
方法的 WebFluxConfigurer
Bean。
转换也可以使用 spring.webflux.format.*
配置属性来自定义。如果没有配置,则将使用以下默认值:
Property | DateTimeFormatter |
---|---|
configprop:spring.webflux.format.date[] |
|
configprop:spring.webflux.format.time[] |
|
configprop:spring.webflux.format.date-time[] |
|
HTTP Codecs with HttpMessageReaders and HttpMessageWriters
Spring WebFlux 使用 HttpMessageReader
和 HttpMessageWriter
接口来转换 HTTP 请求和响应。它们使用 CodecConfigurer
进行配置来查看类路径中可用的库,以获得合理的默认值。
Spring Boot 为编解码器提供了专用的配置属性,spring.codec.
.
It also applies further customization by using CodecCustomizer
instances.
For example, spring.jackson.
配置键应用到 Jackson 编解码器。
如果你需要添加或自定义编解码器,你可以创建一个自定义 CodecCustomizer
组件,如以下示例所示:
Static Content
默认情况下,Spring Boot 从类路径中名为 /static
(或 /public
或 /resources
或 /META-INF/resources
)的目录中提供静态内容。它使用 Spring WebFlux 中的 ResourceWebHandler
,以便可以通过添加你自己的 WebFluxConfigurer
并覆盖 addResourceHandlers
方法来修改该行为。
默认情况下,资源映射到 /
, but you can tune that by setting the configprop:spring.webflux.static-path-pattern[] property.
For instance, relocating all resources to /resources/
上,可按以下方式实现:
spring: webflux: static-path-pattern: "/resources/**"
你还可以使用 spring.web.resources.static-locations
来自定义静态资源位置。这样做会将默认值替换为一个目录位置列表。如果你这样做,默认欢迎页面检测会切换到你的自定义位置。因此,如果你在任何位置上都有 index.html
在启动时,它就是应用程序的主页。
除了前面列出的 “standard” 静态资源位置之外,还为 Webjars content 做了一个特例。默认情况下,如果资源的路径在 /webjars/**
中,则会从 jar 文件中提供这些资源(如果它们以 Webjars 格式打包)。可以用 configprop:spring.webflux.webjars-path-pattern[] 属性自定义路径。
Spring WebFlux 应用程序严格来说并不依赖于 servlet API,因此它们不能作为 war 文件部署,并且不使用 |
Welcome Page
Spring Boot 支持静态欢迎页面和模板化欢迎页面。它首先在配置的静态内容位置中查找一个 index.html
文件。如果没有找到,它会查找一个 index
模板。如果找到任一个,则它会自动用作应用程序的欢迎页面。
这只是一个适用于应用程序定义的实际索引路由的回退。排序是由 HandlerMapping
bean 的顺序定义的,默认情况下如下:
|
使用 |
|
在 |
|
The welcome page support |
Template Engines
除了 REST web 服务之外,你还可以使用 Spring WebFlux 来提供动态 HTML 内容。Spring WebFlux 支持各种模板技术,包括 Thymeleaf、FreeMarker 和 Mustache。
Spring Boot 包含以下模板引擎的自动配置支持:
当使用默认配置将其中一个模板引擎与之一起使用时,会从 src/main/resources/templates
中自动获取模板。
Error Handling
Spring Boot 提供了一个 WebExceptionHandler
,它以一种明智的方式处理所有错误。在处理顺序中的位置紧靠在 WebFlux 提供的处理程序之前,而后者被考虑为最后。对于机器客户端,它生成一个 JSON 响应,其中包含错误的详细信息、HTTP 状态和异常消息。对于浏览器客户端,有一个 “whitelabel” 错误处理程序,它以 HTML 格式呈现相同的数据。你还可以提供自己的 HTML 模板来显示错误(参见 next section)。
在直接自定义 Spring Boot 中的错误处理之前,你可以利用 Spring WebFlux 中的 {url-spring-framework-docs}/web/webflux/ann-rest-exceptions.html[RFC 7807 Problem Details] 支持。Spring WebFlux 可以生成带有 application/problem+json
媒体类型的自定义错误消息,如下所示:
{
"type": "https://example.org/problems/unknown-project",
"title": "Unknown project",
"status": 404,
"detail": "No project found for id 'spring-unknown'",
"instance": "/projects/spring-unknown"
}
可以通过将 configprop:spring.webflux.problemdetails.enabled[] 设置为 true
来启用此支持。
自定义此功能的第一步通常涉及使用现有机制,但替换或扩充错误内容。为此,你可以添加一个 ErrorAttributes
类型的 Bean。
要更改错误处理行为,你可以实现 ErrorWebExceptionHandler
并注册该类型的 Bean 定义。因为 ErrorWebExceptionHandler
相当低级,所以 Spring Boot 还提供了一个方便的 AbstractErrorWebExceptionHandler
,让你以一种 WebFlux 函数式的方式来处理错误,如下例所示:
为了更全面地了解,你还可以直接子类化 DefaultErrorWebExceptionHandler
并覆盖特定的方法。
在某些情况下,控制器级别的错误不会被 web 观测或 metrics infrastructure 记录。应用程序可以通过 {url-spring-framework-docs}/integration/observability.html#observability.http-server.reactive[在观测上下文中设置已处理异常],来确保这些异常被记录到观测中。
Custom Error Pages
如果你想为给定的状态码显示自定义 HTML 错误页面,你可以添加从 error/*
解析的视图,例如通过将文件添加到 /error
目录。错误页面可以是静态 HTML(即,添加到任何静态资源目录下),也可以使用模板构建。文件名称应该是确切的状态码、状态码系列掩码,或者如果其他都不匹配,则为 error
的默认值。请注意,默认错误视图的路径为 error/error
,而使用 Spring MVC 时,默认错误视图为 error
。
例如,要将 404
映射到静态 HTML 文件,你的目录结构如下:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
如果您想使用 Mustache 模板来映射所有 5xx
错误,那么您的目录结构应如下所示:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.mustache
+- <other templates>
Web Filters
Spring WebFlux 提供了一个 WebFilter
接口,可通过该接口实现 HTTP 请求-响应交互的过滤。在应用程序上下文中找到的 WebFilter
Bean 将自动用于过滤每种交互。
如果过滤器的顺序很重要,它们可以实现 Ordered
或使用 @Order
进行标注。Spring Boot 自动配置可以为您配置 Web 过滤器。当它这么做时,将会使用下表中所示的顺序:
Web Filter | Order |
---|---|
|
|
|
|
Embedded Reactive Server Support
Spring Boot 包括对以下嵌入式响应式 Web 服务器的支持:Reactor Netty、Tomcat、Jetty 和 Undertow。大多数开发人员使用适当的“入门包”来获取完全配置的实例。默认情况下,嵌入式服务器在端口 8080 上侦听 HTTP 请求。
Customizing Reactive Servers
可以通过 Spring Environment
属性来配置常见的响应式 Web 服务器设置。通常,您会在 application.properties
或 application.yaml
文件中定义这些属性。
常见的服务器设置包括:
-
网络设置:用于传入的 HTTP 请求的侦听端口 (
server.port
)、绑定到的接口地址 (server.address
) 等。 -
错误管理:错误页的位置 (
server.error.path
) 等。
Spring Boot 尽可能尝试公开常见的设置,但并非总是如此。对于这些情况,诸如 server.netty.*
之类的专用命名空间提供了针对服务器的特定自定义。
请参阅 {code-spring-boot-autoconfigure-src}/web/ServerProperties.java[ |
Programmatic Customization
如果您需要以编程方式配置响应式 Web 服务器,则可以注册一个实现了 WebServerFactoryCustomizer
接口的 Spring Bean。WebServerFactoryCustomizer
提供对 ConfigurableReactiveWebServerFactory
的访问权限,其中包括许多自定义 setter 方法。以下示例来说明如何以编程方式设置端口:
JettyReactiveWebServerFactory
、NettyReactiveWebServerFactory
、TomcatReactiveWebServerFactory
和 UndertowReactiveWebServerFactory
是 ConfigurableReactiveWebServerFactory
的专用变体,分别具有面向 Jetty、Reactor Netty、Tomcat 和 Undertow 的其他自定义 setter 方法。以下示例说明了如何自定义 NettyReactiveWebServerFactory
,它提供了对特定于 Reactor Netty 的配置选项的访问权限:
Customizing ConfigurableReactiveWebServerFactory Directly
对于从 ReactiveWebServerFactory
扩展所需的更高级用例,您可以自己公开此类类型的 Bean。
为许多配置选项提供了 Setter。如果您需要执行更奇特的操作,还提供了几个受保护的方法 “hooks”。有关详细信息,请参阅 source code documentation。
自动配置的定制器仍应用于你的自定义工厂,因此请小心使用该选项。 |
Reactive Server Resources Configuration
在自动配置 Reactor Netty 或 Jetty 服务器时,Spring Boot 将创建特殊 Bean,该 Bean 将为服务器实例提供 HTTP 资源:ReactorResourceFactory
或 JettyResourceFactory
。
默认情况下,还会将这些资源与 Reactor Netty 和 Jetty 客户端共享以获得最佳性能,因为:
-
服务器和客户端使用了相同技术
-
客户端实例是使用 Spring Boot 自动配置的
WebClient.Builder
Bean 构建的
开发者可以通过提供自定义的 ReactorResourceFactory
或 JettyResourceFactory
bean 来覆盖 Jetty 和 Reactor Netty 的资源配置,这将应用于客户端和服务器。
你可以在 WebClient Runtime section 中了解有关客户端资源配置的更多信息。