Project Reactor精髓
1. 目的:设计的目的就是在构建异步管道时避免回调地狱和深层嵌套代码,你可以将响应式应用程序处理的数据视为在装配线上移动
2. 背压:背压是Racctor的核心主题,在使用由Reactor构建的响应式流时,数据从发布者向下传输到订阅者,同时,订阅和需求控制信号从订阅者向上传播到发布者
该库支持常见的背压传播模式
-
仅推送:当订阅者通过subscription.request(Long.MAX_VALUE)请求有效无限数量的元素时
-
仅拉取:当订阅者通过subscription.request(1) 仅在收到前一个元素后请求下一个元素时
-
拉-推:当订阅者有实际控制需求,且发布者可以适应所提出的数据消费速度时
1.2.1 在项目中添加Reactor
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
1.2.2 响应式类型—Flux和Mono
响应式流规范定义4个接口 Publisher<T>、Subscriber<T>、Subscription和Processor<T,R>
Project Reactor提供了Publisher<T>接口的两种实现,即Flux和Mono
1. Flux定义了一个普通的响应式流,它可以产生零个、一个或多个元素,乃至无限元素,尝试收集无限流发出的所有元素可能导致OOM
2. 与Flux相比,Mono定义了一个最多可以生成一个元素的流
Mono和Flux不是相互分离的类型,可以很容易的相互转换,Flux.collectList 返回Mono<List>,而Mono.flux()返回Flux
1.2.3 创建Flux序列和Mono序列
Mono对于包装异步操作(如HTTP请求或数据库查询)非常有用,为此,Mono提供了fromCallable(Callable) FromRunnable(Runnable) FromSupplier(Supplier) FromFuture(CompleteFuture)等
Flux和Mono都有empty()的工厂方法,他们会生成Flux或Mono的空实例,never()方法会创建一个永远不会发出完成、数据或错误等信号的流 error(Throwable)会创建一个序列,该序列在订阅时始终通过每个订阅者的onError(…)方法传递错误
1.2.4 订阅响应式流
一.
Flux和Mono都提供了subscribe()方法的基于lambda的重载,所有重载都返回Disposable接口的实例,用于取消基础的订阅过程
1. subscribe() ;
这是订阅流的最简单方法,因为此方法会忽略所有信号。通常,我们会首选其他变体方法。但是,触发具有副作用的流处理有时也可能很有用。
2. subscribe(Consumer<? super T> consumer) ;
对每个值(onNext信号)调用consumer,而不处理onError和onComplete信号
3. subscribe(@Nullable Consumer<? super T> consumer, Consumer<? super Throwable> errorConsumer) ;
与选项2相同,可以处理onError信号,忽略onComplete信号
4. subscribe(
@Nullable Consumer<? super T> consumer,
@Nullable Consumer<? super Throwable> errorConsumer,
@Nullable Runnable completeConsumer)
与选项3相同但是可以处理onComplete信号
5. subscribe(
@Nullable Consumer<? super T> consumer,
@Nullable Consumer<? super Throwable> errorConsumer,
@Nullable Runnable completeConsumer,
@Nullable Consumer<? super Subscription> subscriptionConsumer)
消费响应流中的所有元素,包括错误处理和完成信号,而且可以通过请求足够数量的数据来控制订阅
6. subscribe(Subscriber<? super T> actual)
最通用的方法,实现subScriber来订阅,建议拓展project reactor提供的BaseSubscriber类
注意:响应式流可以由生产者完成(使用onError或onComplete信号),也可以由订阅着通过SubScription取消,此外,disposable实例也可以取消
1.2.4 用操作符转换响应式序列
1. 映射响应式序列元素
- map操作符将元素转换为目标元素
- cast(Class c)将流的元素强制转换为目标类
- index操作符可用于枚举序列中的元素
2. 过滤响应式序列 - filter操作符
- take(n)方法限制所获取的元素,,该方法忽略前n个元素之外的所有元素
- elementAt(n)只可用于获取序列的第n个元素
3. 收集响应式队列
collectList与collectSortedList()
Flux.distinct()仅传递之前未在流中遇到的元素,全局去重
Flux.distinctUntilChanged()
操作符没有此限制,可用于无限流以删除出现在不间断行中的重复项。