Spring Boot 2系列(六十二):集成 WebFux 实现响应式Web
Spring Framework 5.0 版本增加了响应式 Web 框架 Spring WebFlux 。 它是完全无阻塞的,支持 Reactive Streams 反背压,并且可以在 Netty、Undertow 和 Servlet 3.1+ 容器等服务器上运行。
Spring Boot 通过为 Spring Webflux 提供自动配置来简化响应式 Web 应用程序的开发。
Reactive
Reactive:响应式,指围绕响应变化而构建的编程模型 — 网络组件响应 I/O 事件、UI 控制器响应鼠标事件等。
从这个意义上说,非阻塞是响应式的,因为不是被阻塞,而是在操作完成或数据可用时对通知做出反应。
我们在 Spring 团队中还有另一个与“反应式”相关的重要机制,那就是非阻塞背压。在同步的命令式代码中,阻塞调用是一种自然的背压形式,迫使调用者等待。在非阻塞代码中,控制事件的速率变得很重要,这样快速的生产者就不会压倒它的目的地。
Reactive Streams 是一个小规范(Java 9 也采用),它定义了具有背压的异步组件之间的交互。例如,数据存储库(充当发布者)可以生成 HTTP 服务器(充当订阅者)然后可以写入响应的数据。 Reactive Streams 的主要目的是让订阅者控制发布者生成数据的速度或速度。
Spring WebFlux
Spring Boot 通过为 Spring Webflux 提供自动配置来简化响应式 Web 应用程序的开发。
Spring WebFlux 是 Spring Framework 5.0 中引入的新的响应式 Web 框架。 与 Spring MVC 不同,它不需要 Servlet API,完全异步和非阻塞,并通过 Reactor 项目实现 Reactive Streams 规范。
Spring WebFlux 有两种风格:函数式和基于注释的。 基于注解的模型非常接近 Spring MVC 模型,如下例所示:
注解风格
基于注解的模型非常接近 Spring MVC 模型,如下例所示:
1 |
|
函数式风格
WebFlux.fn 函数式风格,将路由配置与请求的实际处理分开,如下例所示:
路由配置
1 |
|
业务处理
1 |
|
提示: 可以定义任意数量的 RouterFunction Bean
,以将路由器按模块定义。 如果需要设置优先级,可以使用 @Order
注解 Bean 进行排序。
备注:如果在应用程序中同时添加 spring-boot-starter-web 和 spring-boot-starter-webflux 模块,会导致 Spring Boot 自动配置 Spring MVC,而不是 WebFlux。
之所以选择这种行为,是因为许多 Spring 开发人员将 spring-boot-starter-webflux 添加到他们的 Spring MVC 应用程序以使用响应式 WebClient。
您仍然可以通过将所选应用程序类型设置为 SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE)
来强制执行您的选择。
自动配置
Spring Boot 为 Spring WebFlux 提供了自动配置,适用于大多数应用程序。
自动配置在Spring默认设置的基础上添加了以下功能:
- 为 HttpMessageReader 和 HttpMessageWriter 实例配置编解码器(later in this document)。
- 支持提供静态资源,包括对 WebJars 的支持(later in this document)。
如果想保留 Spring Boot WebFlux 的特性并且想添加额外的 WebFlux 配置,可以添加自己的 WebFluxConfigurer 类型的 @Configuration
类,但不需要 @EnableWebFlux
注解。
如果想完全控制 Spring WebFlux,可以添加你自己的带有 @EnableWebFlux
注释的 @Configuration
。
消息转换器
带有HttpMessageReader
和HttpMessageWriter
的HTTP编解码器。
Spring WebFlux 使用 HttpMessageReader 和 HttpMessageWriter 接口转换 HTTP 请求和响应。通过查找类路径中可用的库,使用 CodeConfigurer 对它们进行配置,以获得合理的默认值。
Spring Boot 为编解码器 spring.codec.*
提供了专用的配置属性。 它还通过使用 CodecCustomizer
实例应用进一步的自定义。 例如,spring.jackson.*
配置键应用于 Jackson 编解码器。
如果需要添加或自定义编解码器,可以创建自定义 CodecCustomizer 组件,如下例所示:
1 |
|
静态内容
默认情况下,Spring Boot 从类路径中名为 /static
(或 /public 或 /resources 或 /META-INF/resources)的目录中提供静态内容。 它使用来自 Spring WebFlux 的 ResourceWebHandler
,因此可以通过添加自己的 WebFluxConfigurer
并覆盖 addResourceHandlers
方法来修改该行为。
默认情况下,资源映射到 /**
,但可以通过设置 spring.webflux.static-path-pattern
属性来调整它。 例如,将所有资源重定位到 /resources/**
,如下配置:
1 | /resources/** = |
还可以使用spring.web.resources.static-locations
自定义静态资源位置。这样做将用目录位置列表替换默认值。
如果这样做,默认的欢迎页面检测将切换到自定义位置。所以,如果在启动时的任何位置有一个 index.html
,它就是应用程序的主页(Home Page)。
除了前面列出的“标准”静态资源位置之外,还为 Webjars 内容做了一个特殊情况。 任何具有 /webjars/**
路径的资源如果以 Webjars 格式打包,则从 jar 文件中提供。
相关参考
Spring Boot 2系列(六十二):集成 WebFux 实现响应式Web