Spring 5 WebFlux的反应式编程
介绍
Spring WebFlux是Spring对日益增长的阻塞I / O体系结构问题的回应。
随着数据在我们这个时代变得越来越重要,我们采取的检索和处理数据的方法也在发生变化。 按照惯例,大多数方法都是“阻塞”的,或者说是同步的 。 这意味着访问资源会阻止应用程序访问/处理另一资源,直到处理了先前的资源为止。
尽管通过高性能应用程序对数据的需求不断增长,但是在有限的数据和资源量的情况下,这是完全可以的,这成为一个巨大的问题。
解决方案很明显-让更多的文员处理客户。 在软件应用程序方面,这意味着多线程环境和异步,非阻塞调用。
spring反应式编程
由Spring MVC组成的Spring流行的servlet堆栈使用访问和处理数据的常规方法作为同步调用。 随着Spring 5的推出,Spring的反应式是在Reactor Core之上构建的。
Spring的反应式堆栈为Netty和Servlet 3.1+容器提供了额外的支持,从而提高了反应式应用程序的性能:
Spring WebFlux是Spring MVC的对应模块。 在Spring MVC实现同步,阻塞I / O的地方,Spring WebFlux通过Reactive Streams实现反应编程。
尽管可以自由地将它们组合在一起,但是通常将使用其中一个。
Spring WebFlux依赖关系
通过Spring Initializr初始化一个普通的Spring Boot项目,添加一个依赖项就足够了:
spring-boot-starter-webflux
包括spring-web
, spring-webflux
, spring-boot-starter
, spring-boot-starter-reactor-netty
等,因此不需要任何其他依赖项。
对于使用Gradle进行依赖关系管理的应用程序,可以将Spring WebFlux添加到应用程序的build.gradle
文件中:
在Spring WebFlux中,从任何操作返回的数据都打包到响应流中。 这种方法体现了两种类型,它们是WebFlux应用程序的构建块-Mono和Flux
。
Mono
是返回零个项目或单个项目( 0..1
)的流,而Flux
是返回零个或多个项目( 0..N
)的流。
因此,在期望单个(或没有)结果(例如从数据库中检索唯一用户)时,将使用Mono
,而在期望多个结果或某种类型的集合时,将使用Flux
。
Spring WebFlux控制器
与我们在经典Spring MVC中使用控制器的方式类似,为了创建异步REST API,我们使用WebFlux控制器。 甚至命名约定也类似,以确保在这两种方法之间轻松转换。
为了将一个类标记为控制器,我们在类级别使用@RestController
批注。
在类路径中具有Spring WebFlux和Reactor Core依赖项将使Spring知道@RestController
实际上是一个反应组件,并添加对Mono
和Flux
支持。
Spring WebFlux配置
按照Spring Boot的标准,我们将通过注释处理配置。 @Configuration
和@EnableWebFlux
批注将一个类标记为配置类,Spring的bean管理人员将其注册:
要使用或扩展现有的WebFlux配置API,可以扩展WebFluxConfigurer
接口:
带有Spring WebFlux的CORS
WebFlux还提供CORS(跨源资源共享)支持,与Spring MVC Servlet堆栈非常相似。 可以在项目级别以及控制器和控制器方法级别设置CORS配置。
要在项目级别添加CORS配置,您需要从WebFluxConfigurer
界面addCorsMappings()
方法:
为了更详细地添加CORS配置,使用了@CrossOrigin
批注。 这允许在控制器和方法级别指定CORS详细信息。
在控制器类级别使用@CrossOrigin
时,所有方法级别的CORS设置都将从类级别配置继承:
Spring Webflux的安全性
Spring还为其WebFlux框架提供了标准的安全性选项。 您需要在类级别添加@EnableWebFluxSecurity
,以在项目中启用安全性配置:
Spring WebFlux Web客户端
Spring WebFlux还包括一个反应式Web客户端,用于管理REST调用。 默认情况下,使用Reactor-Netty与WebFlux服务器进行通信。
可以使用静态工厂方法或通过其构建器方法(更多的自定义)来创建WebFlux客户端对象。
静态工厂方法是WebClient.create()
和WebClient.create(String baseUrl)
。 另一方面, WebClient.builder
提供以下选项以向Web客户端对象添加更多详细信息:
uriBuilderFactory
defaultHeader
defaultCookie
defaultRequest
filter
exchangeStrategies
clientConnector
我们将在构建演示应用程序的进行部分中对此进行仔细研究。
演示申请
我们将使用WebFlux的标准组件创建一个简单的反应式REST API,它将用作反应式服务器。 然后,将构建一个反应式Web客户端应用程序,该应用程序从该服务器检索信息并处理数据。
WebFlux Web服务器
资料库
首先,通过创建反应式存储库接口为反应式应用程序奠定基础。
我们从WebFlux的ReactiveCrudRepository
扩展了存储库,该存储库将根据Mono
或Flux
数据类型返回数据,具体取决于可以检索的元素数。
要将MongoDB与Spring WebFlux结合使用,我们将添加一个配置类,该类告诉Spring应该将数据库作为反应性组件进行处理:
控制者
完成并配置数据层后,让我们创建一个简单的REST控制器,该控制器将通过GET请求检索Mono
和Flux
资源:
在这里,我们使用反应式ResourceRepository
来查找来自请求的id
的资源。 由于我们正在寻找唯一的ID,因此预期结果是1条记录(找到带有传递ID的资源)或0条记录(数据库中没有记录),因此将Mono
用作返回类型。
由于findAll()
可以返回一个以上的资源元素(如果存在),因此将Flux
用作返回类型。
WebFlux Web客户端
现在我们已经建立了一个基本的REST应用程序,让我们创建一个Spring WebFlux客户端,该客户端可以将请求发送到WebFlux REST应用程序。
要启动Web客户端,我们需要使用服务器URL创建一个WebClient
对象:
创建WebClient
对象后,我们可以使用它向Web服务器发出请求。
让我们向服务器发出请求,以给定ID检索资源:
bodyToMono()
方法负责将响应的正文包装到Mono
。
同样,如果调用端点将数据返回为Flux
则可以使用以下方法检索它:
结论
Spring框架允许开发人员使用Spring的WebFlux堆栈制作反应性,非阻塞的应用程序和API。 WebFlux提供的注释与经典Spring MVC应用程序中使用的注释非常相似,这使开发人员可以更轻松地过渡到反应式代码。
在本指南中,我们介绍了WebFlux框架的最重要概念,并构建了一个演示应用程序以在实践中展示它们。