webflux是spring框架中用来和springmvc进行互补的,一套全新的非阻塞响应式流处理框架。其中响应式流处理的依赖包,webflux选择的是Reactor。
下面来简单介绍一下Reactor
核心接口Reactive Streams
reactor实现的是org.reactivestreams的一套标准接口reactive-streams
Reactive Streams的目的是为具有非阻塞背压的异步流处理提供标准。
由以下组件组成
Publisher
package org.reactivestreams;
/**
发布者是可能无限数量的有序元素的提供者,根据从其订阅者收到的需求发布它们。
发布者可以在不同的时间点动态地为多个订阅者订阅订阅(订阅者)。
*/
public interface Publisher<T> {
/**
请求Publisher启动流数据。
这是一个“工厂方法”,可以多次调用,每次启动一个新的订阅。
每个订阅仅适用于一个订阅者。
订阅者只应订阅一个发布者一次。
如果发布者拒绝订阅尝试或以其他方式失败,它将通过Subscriber.onError发出错误信号。
*/
public void subscribe(Subscriber<? super T> s);
}
Subscriber
package org.reactivestreams;
/**
将订阅者实例传递给Publisher.subscribe(订阅者)后,将接收对onSubscribe(订阅)的调用。
在调用Subscription.request(long)之前不会收到进一步的通知。
发出信号后需求:
onNext(Object)的一次或多次调用,最多为Subscription.request(long)定义的最大数量
单次调用onError(Throwable)或onComplete(),它指示终端状态,之后不再发送任何事件。
只要Subscriber实例能够处理更多内容,就可以通过Subscription.request(long)发出需求信号。
*/
public interface Subscriber<T> {
/**
调用Publisher.subscribe(订阅者)后调用。
在调用Subscription.request(long)之前,任何数据都不会开始流动。
只要需要更多数据,此Subscriber实例就有责任调用Subscription.request(long)。
发布者仅在响应Subscription.request(long)时发送通知。
*/
public void onSubscribe(Subscription s);
/**
* 发布者为响应对Subscription.request(long)的请求而发送的数据通知。
* @param t the element signaled
*/
public void onNext(T t);
/**
终端状态失败。
即使再次调用Subscription.request(long),也不会发送更多事件。
*/
public void onError(Throwable t);
/**
成功的终端状态。
即使再次调用Subscription.request(long),也不会发送更多事件。
*/
public void onComplete();
}
Subscription
package org.reactivestreams;
/**
订阅表示订阅发布者的订阅者的一对一生命周期。
它只能由一个订阅者使用一次。
它用于表示对数据的需求和取消需求(并允许资源清理)。
*
*/
public interface Subscription {
/**
在通过此方法发出需求信号之前,发布者不会发送任何事件。
然而,无论何时需要,它都可以被调用 - 但是未完成的累积需求绝不能超过Long.MAX_VALUE。 Long.MAX_VALUE的未完成累积需求可能会被发布者视为“有效无限制”。
发布者可以发送任何请求,因此只需要发出可以安全处理的信号需求。
如果流结束但发布者可以发送少于请求的发送者,但必须发出Subscriber.onError(Throwable)或Subscriber.onComplete()。
PARAMS:
n - 向上游发布者请求的严格正数元素
*/
public void request(long n);
/**
请求发布者停止发送数据并清理资源。
在呼叫取消后,仍可以发送数据以满足先前发出的信号要求。
*/
public void cancel();
}
Processor
package org.reactivestreams;
/**
处理器代表一个处理阶段 - 既是订阅者又是发布者,并遵守两者的合同。
类型参数:
<T> - 发信号通知订阅者的元素类型
<R> - 发布者发出信号的元素类型
*/
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {
}
demo讲解
Reactor引入了可实现Publisher的可组合响应式类型,同时也提供了丰富的运算符:Flux和Mono。Flux对象表示0…N项的响应式序列,而Mono对象表示单值或空(0…1)结果。
demo1
import reactor.core.publisher.Flux;
/**
* Created by aaron on 2018/9/27.
*/
public class FluxSample {
public void demo1(){
//构建一个Flux,它从头开始只发出一系列计数递增整数。
//start - 要发出的第一个整数 ; count - 要发出的递增值的总数,包括第一个值
Flux<Integer> ints = Flux.range(2, 4); //分解步骤1
//将消费者订阅到此Flux,它将分别消耗序列中的所有元素,处理错误并对完成做出反应。
ints.subscribe( //分解步骤2
//实现一个消费者(注意无返回结果)
i -> System.out.println(i),
//实现一个可以调用的错误信号的消费者
error -> System.err.println("Error " + error),
//实现一个在发送一个完成信号后的回调
() -> System.out.println("Done"));
}
public static void main(String[] args) {
FluxSample fluxSample = new FluxSample();
fluxSample.demo1();
}
}
分解步骤1
通过Flux.range(2, 4)创建了一个Flux,发送一系列计数递增整数
public static Flux<Integer> range(int start, int count) {
if (count == 1) {
return just(start);
}
if (count == 0) {
return empty();
}
return onAssembly(new FluxRange(start, count));
}
protected static <T> Flux<T> onAssembly(Flux<T> source) {
//这里的hook为null,直接返回source
Function<Publisher, Publisher> hook = Hooks.onEachOperatorHook;
if(hook == null) {
return source;
}
return (Flux<T>)hook.apply(source);
}
//最终创建的是一个FluxRange对象,对start和end属性进行了赋值
final class FluxRange extends Flux<Integer> implements Fuseable, Scannable {
final long start;
final long end;
FluxRange(int start, int count) {
if (count < 0) {
throw new IllegalArgumentException("count >= required but it was " + count);
}
//end被赋值为start + count
long e = (long) start + count;
if (e - 1 > Integer.MAX_VALUE) {
throw new IllegalArgumentException("start + count must be less than Integer.MAX_VALUE + 1");
}
this.start = start;
this.end = e;
}
...
}
分解步骤2
ints.subscribe这个方法触发了一个消费者对发布(Flux)的订阅,这里订阅将请求无限制的需求(Long.MAX_VALUE)
/*
consumer - 要调用每个值的使用者
errorConsumer - 调用错误信号的消费者
completeConsumer - 消费者调用完整信号
*/
public final Disposable subscribe(
@Nullable Consumer<? super T> consumer,
@Nullable Consumer<? super Throwable> errorConsumer,
@Nullable Runnable completeConsumer) {
return subscribe(consumer, errorConsumer, completeConsumer, null);
}
public final Disposable subscribe(
@Nullable Consumer<? super T> consumer,
@Nullable Consumer<? super Throwable> errorConsumer,
@Nullable Runnable completeConsumer,
@Nullable Consumer<? super Subscription> subscriptionConsumer) {
//这里最终是创建了一个LambdaSubscriber(一个Subscriber的实现类)
return subscribeWith(new LambdaSubscriber<>(consumer, errorConsumer,
completeConsumer,
subscriptionConsumer));
}
//一个无边界Java Lambda的Subscriber适配器
final class LambdaSubscriber<T>
implements InnerConsumer<T>, Disposable {
final Consumer<? super T> consumer;
final Consumer<? super Throwable> errorConsumer;
final Runnable completeConsumer;
final Consumer<? super Subscription> subscriptionConsumer;
volatile Subscription subscription;
...
/**
创建订阅者,对onNext,onError和onComplete做出反应。 订阅者将自动请求订阅Long.MAX_VALUE。
*/
LambdaSubscriber(
@Nullable Consumer<? super T> consumer,
@Nullable Consumer<? super Throwable> errorConsumer,
@Nullable Runnable completeConsumer,
@Nullable Consumer<? super Subscription> subscriptionConsumer) {
this.consumer = consumer;
this.errorConsumer = errorConsumer;
this.completeConsumer = completeConsumer;
this.subscriptionConsumer = subscriptionConsumer;
}
...
@Override
public final void onNext(T x) {
try {
if (consumer != null) {
//这里调用的就是 i -> System.out.println(i),参数x对应i
consumer.accept(x);
}
}
catch (Throwable t) {
Exceptions.throwIfFatal(t);
this.subscription.cancel();
onError(t);
}
}
...
@Override
public final void onComplete() {
Subscription s = S.getAndSet(this, Operators.cancelledSubscription());
if (s == Operators.cancelledSubscription()) {
return;
}
if (completeConsumer != null) {
try {
//这里调用的complete以后的回调
//() -> System.out.println("Done")); 将会输出"Done"
completeConsumer.run();
}
catch (Throwable t) {
Exceptions.throwIfFatal(t);
onError(t);
}
}
}
...
}
上面的代码介绍到subscribeWith(new LambdaSubscriber<>(…))这行。下面来继续追踪subscribeWith(…)这个方法
序号 | 类 | 方法 |
---|---|---|
1 | Flux | 6870 return subscribeWith(new LambdaSubscriber<>(…) |
2 | Flux | 7044 subscribe(subscriber); |
3 | Flux | 6877 onLastAssembly(this).subscribe(Operators.toCoreSubscriber(actual)); |
4 | FluxRange | 52 public void subscribe(CoreSubscriber<? super Integer> actual) { |
5 | LambdaSubscriber | 75 public final void onSubscribe(Subscription s) { |
6 | FluxRange.RangeSubscription | 103 public void request(long n) { |
7 | FluxRange.RangeSubscription | 120 void fastPath() { |
到这里就进入了真正执行onNext或者onComplete相关的方法了
void fastPath() {
final long e = end;
//这里的a就是LambdaSubscriber
final Subscriber<? super Integer> a = actual;
for (long i = index; i != e; i++) {
if (cancelled) {
return;
}
//这里循环执行onNext,对应LambdaSubscriber中的onNext
a.onNext((int) i);
}
if (cancelled) {
return;
}
//这里循环执行onComplete,对应LambdaSubscriber中的onComplete
a.onComplete();
}
这里循环结束就输出“Done”,走完了整个demo