工程地址,分支为reactive-stack
。
Web层的Reactive:Spring WebFlux
Spring WebFlux是异步的非阻塞的
传统的Spring MVC基于Servlet,是阻塞式的,每次请求由一个线程处理;而Spring WebFlux通过事件循环Event Loop
的方式,由单个线程非阻塞的处理事件。当需要处理耗时任务时,Event Loop
绑定的线程会新启线程来执行,完成后通知Event Loop
。
与Spring MVC的关系
Spring WebFlux- Spring MVC基于Servlet API,需要运行在Servlet容器中,如Tomcat。
- Spring WebFlux不依赖于Servlet API,可以运行在基于Netty等网络服务器上。
- 用在
Controller
层的注解,如@Controller
,@RequestMapping
等是通用的。
使用Spring WebFlux
- 引入依赖
spring-boot-starter-webflux
内置的服务器是Netty,而不是Tomcat。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
- 全流程Reactive技术栈
从Controller到Service、Repository层,都采用Reactive模式。每一层的数据都返回Flux
或Mono
类型,框架会自动调用subscribe
方法,以使数据流动。
Repository层的Reactive
目前支持Reactive模式的数据存储只有Redis,MongoDB等,传统的关系型数据库和相应的JDBC驱动还不支持。
但是可以将Repository返回的模型或集合转换为Reactive类型:
- 集合 -> Flux<T> : 通过
fromIterable
等方法 - 模型 -> Mono<T> : 通过
just
方法
List<Person> personList = personRepository.findAll();
Flux<Person> personFlux = Flux.fromIterable(personList);
也可以将Flux或Mono中的数据元素提取出来,即转换为传统模型:
- Flux<T> -> 集合 : 通过
toIterable
等方法 - Mono<T> -> 模型 : 通过
block
方法
Iterable<Person> personIterable = personFlux.toIterable();
Person person = personMono.block();
注意:
toIterable()
,block()
等提取数据的方式都是阻塞的。
当然,要实现全流程的Reactive模式,需要MongoDB等文档数据库。
上述的类型转换是在已有传统关系型数据库,无法换库时采用的方案,即在Repository层仍然是非Reactive模式的,在Service层将模型或集合转换为Reactive类型,这样在Controller层可以使用。
网友评论