Spring WebFlux以类似于SpringMVC的带注释的控制器格式为web应用程序提供反应式、异步、无阻塞的编程支持。
这种方法类似于Node.js如何使用异步、非阻塞模型,这有助于提高其可伸缩性。Spring WebFlux使用了一个类似的模型,但是有多个事件循环。
Spring WebFlux摆脱了传统SpringMVC中的每请求线程阻塞模型(默认情况下使用Tomcat),转而使用多事件循环、异步、非阻塞(默认情况下使用Netty)范式,该范式具有比传统阻塞代码更具伸缩性和效率的背压。
有关使用Java进行反应式函数编程的更一般的介绍,请参见:https://medium.com/javarevisited/intro-to-reactive-functional-programming-d49e00365847
Spring Reactive技术栈:
Spring Reactive栈包括:
- Spring Boot 2+
- Project Reactor
- Spring WebFlux
- Netty(作为默认的web服务器,而不是Tomcat)
- Spring Data Reactive Repositories
为什么使用Spring WebFlux?
Spring WebFlux将允许您更有效地利用CPU和网络资源,提供更具可伸缩性的体系结构和更具响应性的用户体验。
为什么会创建SpringWebFlux?
部分原因是需要一个无阻塞的web堆栈来处理具有少量线程的并发性,并使用较少的硬件资源进行扩展。
这一点很重要,因为像Netty这样的服务器在异步、非阻塞空间中已经建立良好。
答案的另一部分是函数式编程。
java8中lambda表达式的添加为Java中的函数api创造了机会。这对于允许异步逻辑的声明性组合的非阻塞应用程序和延续式api是一个福音。
Spring WebFlux框架
Spring WebFlux构建在projectreactor上,projectreactor实现了Reactive Streams
规范。
从反应流文档:
- Reactive Streams是一个为具有非阻塞背压的异步流处理提供标准的方案。
- 这包括针对运行时环境(JVM和JavaScript)以及网络协议的工作。
WebFlux支持两种模式:
- 基于注释的Spring控制器(类似于SpringMVC)
- 允许功能性的、流畅的API样式的路由和处理函数的功能端点
Spring WebFlux的作用:
Spring Boot Starters
Spring Boot公开了Spring WebFlux反应式web应用的springbootstarter:springbootstarterwebflux
Maven:
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Gradle:
//https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux
compile('org.springframework.boot:spring-boot-starter-webflux')
您还可以考虑为您的测试类引入这个依赖项:io.projectreactor:reactor-test
当从Spring初始化器引导应用程序时,一定要选择Spring Reactive Web作为依赖项。
您还需要利用Spring Data Reactive依赖关系来获得反应式、异步、非阻塞体系结构的全部好处。
Spring Data Reactive库示例:
- Spring Data Reactive for Apache Cassandra
- Spring Data Reactive MongoDB
- Spring Data Reactive Redis
- 。。。
带注释的Spring WebFlux RestController控制器
以下是带注释的Spring WebFlux控制器的示例:
Spring WebFlux控制器示例
@RestController
@RequestMapping("api/v1/room/reservation/")
public class ReservationResource {
@GetMapping(path = "/{roomId}")
public Mono<Reservation> getReservationById(@PathVariable Mono<String> roomId) {
return //Call your service layer here
}
}
在使用Spring WebFlux和Angular的全反应式应用程序的上下文中查看此控制器的源代码:
https://github.com/anataliocs/reactiveapp2019/blob/master/src/main/java/com/linkedinlearning/reactiveapp/controller/ReservationResource.java
正如您所看到的,这段代码与springmvc非常相似,只是返回类型是一个被动发布者,在本例中是一个发出Reservation
对象(来自这个示例项目的DTO)的Mono。
Mono:一种反应式发布服务器,它发出1个或0个元素,而不是终止。
换句话说,Mono就像一个异步的、承诺的或未来的元素。
从Mono类型的Spring JavaDocs中:
带有基本rx运算符的反应流发布器,通过onNext
信号最多发出一个项目,然后以onComplete
信号终止(成功的Mono,有值或无值),或者只发出一个onError
信号(失败的Mono)。
Mono的作用:
Mono的订户将收到一个发射的元素(或错误信号),然后是一个完成信号。
使用Spring Data Reactive仓库
既然您有了一个反应式控制器,那么您就需要连接到一个利用Spring Data Reactive存储库的服务层。
Spring Data Reactive库示例
public interface ReactiveReservationRepository
extends ReactiveCrudRepository<Reservation, String> {
Mono<Reservation> findById(Mono<String> roomId);
}
有关如何配置Spring响应数据的更多详细信息,请参阅本文:https://spring.io/blog/2016/11/28/going-reactive-with-spring-data
从WebFlux控制器调用反应式存储库
@RestController
@RequestMapping("api/v1/room/reservation/")
public class ReservationResource {
...
@GetMapping(path = "/{roomId}")
public Mono<Reservation> getReservationById(@PathVariable Mono<String> roomId) {
// It is implied this @Bean is @Autowired into this class
return reactiveReservationRepository.findById(roomId);
}
...
}
如果使用服务层,请确保将服务方法的返回类型设置为Mono
或Flux
之类的被动发布器。
查看这个Github repo以获得反应式应用程序的完整示例:https://github.com/anataliocs/reactiveapp2019
除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/2001.html
暂无评论