背景
通过一个最简单的发布订阅流程探究底层机制
scss
Flux.fromIterable(Arrays.asList(1, 2, 3, 4, 5))
.filter(n -> n % 2 == 0)
.map(n -> n * 10)
.subscribe(System.out::println);
我们将从 subscribe 方法开始,详细分析订阅关系如何构建,层层嵌套形成完整的订阅链。
订阅关系构建的整体过程
订阅关系构建的核心是:通过 subscribe 方法将订阅者(Subscriber)与发布者(Publisher)关联起来,并在操作符链中插入中间订阅者,形成一个从下游到上游的订阅链。这个过程可以分为以下几个阶段:
- 触发订阅:调用 subscribe,传入最终订阅者。
- 操作符链的逆向构建:从最下游的操作符(map)开始,逐层向上游(filter、fromIterable)传播订阅请求,创建中间订阅者。
- 订阅关系的建立:每个操作符生成一个 Subscription 对象,绑定上下游,形成嵌套结构。
- 数据流准备:订阅链构建完成后,等待数据请求(request)触发数据流。
订阅关系构建是从下游到上游的,而数据流是从上游到下游的。这种反向构建是 Reactive Streams 规范的核心设计。
详细分析订阅关系构建
我们从 subscribe(System.out::println) 开始,逐步拆解订阅关系的构建过程。
触发订阅:subscribe 方法
调用 subscribe(System.out::println) 时,subscribe 方法的作用是将 System.out::println(一个 Consumer)包装为一个订阅者,并启动订阅流程。
源码分析:
Flux 类的 subscribe(Consumer) 方法定义如下:
java
public final void subscribe(Consumer<? super T> consumer) {
Objects.requireNonNull(consumer, "consumer");
subscribe(consumer, null, null);
}
- 检查 consumer 不为 null。
- 调用重载方法 subscribe(Consumer, Consumer, Runnable),传入 consumer(System.out::println),错误和完成回调为 null。
接着看重载方法:
java
public final void subscribe(Consumer<? super T> consumer,
Consumer<? super Throwable> errorConsumer,
Runnable completeConsumer) {
subscribe(new LambdaSubscriber<>(consumer, errorConsumer, completeConsumer, null));
}
- 创建一个 LambdaSubscriber 实例,将 System.out::println 包装为订阅者。
- 调用 subscribe(Subscriber) 方法,传入 LambdaSubscriber。
最终调用的是:
ini
public final void subscribe(Subscriber<? super T> s) {
CorePublisher publisher = Operators.onLastAssembly(this);
CoreSubscriber subscriber = Operators.toCoreSubscriber(s);
publisher.subscribe(subscriber);
}
- this 是当前的 Flux(经过 map 操作后的 FluxMap)。
- Operators.onLastAssembly 处理调试信息(通常返回 this 本身)。
- Operators.toCoreSubscriber 将 Subscriber 转换为 CoreSubscriber(内部优化接口)。
- 调用 publisher.subscribe(subscriber),将订阅者绑定到发布者。
小结:
- subscribe(System.out::println) 创建了一个 LambdaSubscriber,并调用 FluxMap.subscribe(LambdaSubscriber)。
- 此时,LambdaSubscriber 是最终的订阅者,负责打印 [20, 40]。
操作符链的逆向构建
FluxMap 的订阅
FluxMap 是操作符链的最下游,接下来我们分析它如何向上游传播订阅请求,构建嵌套的订阅关系。 FluxMap 的 subscribe 方法定义如下:
typescript
@Override
public void subscribe(CoreSubscriber<? super T> actual) {
source.subscribe(new MapSubscriber<>(actual, mapper));
}
- source 是上游的 Flux(这里是 FluxFilter,因为 map 的上游是 filter)。
- actual 是下游的订阅者(这里是 LambdaSubscriber)。
- 创建一个 MapSubscriber,传入 actual(LambdaSubscriber)和 mapper(n -> n * 10)。
- 调用 source.subscribe,将 MapSubscriber 作为订阅者传递给上游。
MapSubscriber 的作用:
- 接收上游数据,应用 mapper 转换后传递给下游。
- 它的构造方法是:
kotlin
MapSubscriber(CoreSubscriber<? super R> actual, Function<? super T, ? extends R> mapper) {
this.actual = actual;
this.mapper = mapper;
}
- actual 是 LambdaSubscriber。
- mapper 是 n -> n * 10。
小结:
- FluxMap 创建了一个 MapSubscriber,作为中间订阅者,连接下游的 LambdaSubscriber 和上游的 FluxFilter。
- 订阅请求传递到 FluxFilter.subscribe(MapSubscriber)。
FluxFilter 的订阅
FluxFilter 的 subscribe 方法如下:
typescript
@Override
public void subscribe(CoreSubscriber<? super T> actual) {
source.subscribe(new FluxFilter.FilterSubscriber<>(actual, predicate));
}
- source 是上游的 Flux(这里是 FluxFromIterable)。
- actual 是下游的订阅者(这里是 MapSubscriber)。
- 创建一个 FilterSubscriber,传入 actual(MapSubscriber)和 predicate(n -> n % 2 == 0)。
- 调用 source.subscribe,将 FilterSubscriber 传递给上游。
FilterSubscriber 的作用:
- 接收上游数据,应用 predicate 过滤后传递给下游。
- 构造方法是:
kotlin
FilterSubscriber(CoreSubscriber<? super T> actual, Predicate<? super T> predicate) {
this.actual = actual;
this.predicate = predicate;
}
- actual 是 MapSubscriber。
- predicate 是 n -> n % 2 == 0。
小结:
- FluxFilter 创建了一个 FilterSubscriber,连接下游的 MapSubscriber 和上游的 FluxFromIterable。
- 订阅请求传递到 FluxFromIterable.subscribe(FilterSubscriber)。
FluxFromIterable 的订阅
FluxFromIterable 是数据流的起点,它的 subscribe 方法如下:
kotlin
@Override
public void subscribe(CoreSubscriber<? super T> actual) {
Iterator<?> iterator;
try {
iterator = Objects.requireNonNull(iterable.iterator(), "The iterator returned is null");
} catch (Throwable e) {
Operators.error(actual, Operators.onOperatorError(e, actual.currentContext()));
return;
}
actual.onSubscribe(new IterableSubscription<>(actual, iterator));
}
- actual 是下游的订阅者(这里是 FilterSubscriber)。
- 从 iterable(Arrays.asList(1, 2, 3, 4, 5))获取迭代器。
- 创建一个 IterableSubscription,传入 actual(FilterSubscriber)和迭代器。
- 调用 actual.onSubscribe,将 IterableSubscription 传递给 FilterSubscriber。
IterableSubscription 的作用:
- 作为 Subscription 的实现,管理数据请求和发送。
- 从迭代器生成数据,响应 request(n) 调用。
小结:
- FluxFromIterable 创建了 IterableSubscription,而订阅关系是连接下游订阅者 FilterSubscriber 和数据源(List)的桥梁
- 至此,订阅链构建完成。
Subscription 订阅关系的构建与触发
从 FluxFromIterable 调用 FilterSubscriber.onSubscribe 开始,继续分析后续链路。
- onSubscribe 的触发与传递
在订阅关系构建的最后一步,FluxFromIterable 的 subscribe 方法调用了:
typescript
@Override
public void subscribe(CoreSubscriber<? super T> actual) {
Iterator<?> iterator = iterable.iterator();
actual.onSubscribe(new IterableSubscription<>(actual, iterator));
}
- actual 是 FilterSubscriber。
- 创建 IterableSubscription 并调用 FilterSubscriber.onSubscribe。
1.1 FilterSubscriber.onSubscribe
FilterSubscriber 继承自 BaseSubscriber 或类似基类,其 onSubscribe 方法通常由 Operators 工具类实现。实际行为类似于:
kotlin
@Override
public void onSubscribe(Subscription s) {
if (Operators.validateSubscription(this.s, s)) {
this.s = s;
actual.onSubscribe(this);
}
}
- s 是 IterableSubscription。
- Operators.validateSubscription 检查订阅是否有效(防止重复订阅)。
- this.s 保存上游的 Subscription,用于后续请求数据。
- actual 是下游的 MapSubscriber,调用 actual.onSubscribe(this),将 FilterSubscriber 自身作为 Subscription 传递给下游。
关键点:
- FilterSubscriber 既是 Subscriber(接收上游信号),也是 Subscription(向下游提供控制接口)。
- 它将 IterableSubscription 包装后传递给下游,形成嵌套的 Subscription 链。
1.2 MapSubscriber.onSubscribe
MapSubscriber 的 onSubscribe 逻辑类似:
kotlin
@Override
public void onSubscribe(Subscription s) {
if (Operators.validateSubscription(this.s, s)) {
this.s = s;
actual.onSubscribe(this);
}
}
- s 是 FilterSubscriber。
- 保存上游的 Subscription(FilterSubscriber)。
- actual 是 LambdaSubscriber,调用 actual.onSubscribe(this),将 MapSubscriber 传递给下游。
1.3 LambdaSubscriber.onSubscribe
LambdaSubscriber 是最终订阅者,其 onSubscribe 定义如下:
typescript
@Override
public void onSubscribe(Subscription s) {
if (Operators.setOnce(S, this, s)) {
if (requestConsumer != null) {
requestConsumer.accept(s);
} else {
s.request(Long.MAX_VALUE);
}
}
}
- s 是 MapSubscriber。
- Operators.setOnce 确保订阅只设置一次。
- requestConsumer 默认为空,因此调用 s.request(Long.MAX_VALUE),请求无限数据。
小结:
-
onSubscribe 从上游到下游逐层传递:
- IterableSubscription → FilterSubscriber
- FilterSubscriber → MapSubscriber
- MapSubscriber → LambdaSubscriber
-
最终,LambdaSubscriber 触发 request(Long.MAX_VALUE),启动数据流。
- 数据请求的触发
LambdaSubscriber 调用 MapSubscriber.request(Long.MAX_VALUE),请求数据。接下来,请求信号从下游到上游传递。
2.1 MapSubscriber.request
MapSubscriber 继承自 BaseSubscriber 或类似类,其 request 方法如下:
java
@Override
public void request(long n) {
s.request(n);
}
- s 是上游的 FilterSubscriber。
- 将请求直接传递给 FilterSubscriber。
2.2 FilterSubscriber.request
FilterSubscriber 的 request 方法类似:
java
@Override
public void request(long n) {
s.request(n);
}
- s 是上游的 IterableSubscription。
- 将请求传递给 IterableSubscription。
2.3 IterableSubscription.request
IterableSubscription 的 request 方法是数据流的实际起点:
scss
@Override
public void request(long n) {
if (Operators.validate(n)) {
if (Operators.addCap(REQUESTED, this, n) == 0) {
if (n == Long.MAX_VALUE) {
fastPath();
} else {
slowPath(n);
}
}
}
}
- Operators.validate(n) 检查请求是否有效(n > 0)。
- Operators.addCap 累加请求数,避免溢出。
- 因为 n == Long.MAX_VALUE,执行 fastPath():
ini
void fastPath() {
final CoreSubscriber<? super T> a = actual;
final Iterator<?> it = iterator;
for (;;) {
if (cancelled) return;
boolean hasNext;
try {
hasNext = it.hasNext();
} catch (Throwable ex) {
Operators.error(a, Operators.onOperatorError(this, ex, a.currentContext()));
return;
}
if (cancelled) return;
if (!hasNext) {
if (!cancelled) a.onComplete();
return;
}
T t;
try {
t = Objects.requireNonNull(it.next(), "Iterator returned a null value");
} catch (Throwable ex) {
Operators.error(a, Operators.onOperatorError(this, ex, a.currentContext()));
return;
}
if (cancelled) return;
a.onNext(t);
}
}
- actual 是 FilterSubscriber。
- iterator 是 List 的迭代器。
- 循环遍历 [1, 2, 3, 4, 5],逐个调用 FilterSubscriber.onNext。
- 数据发送完后,调用 FilterSubscriber.onComplete。
- 数据流的处理
数据从上游到下游流动,经过每个订阅者的处理。
3.1 FilterSubscriber.onNext
FilterSubscriber 的 onNext 方法:
typescript
@Override
public void onNext(T t) {
if (isCancelled()) return;
if (predicate.test(t)) {
actual.onNext(t);
}
}
-
t 是从 IterableSubscription 收到的数据(如 1、2 等)。
-
predicate 是 n -> n % 2 == 0。
-
如果 t 通过过滤(是偶数),调用 actual.onNext(t)(actual 是 MapSubscriber)。
-
处理过程:
- 1:不通过,丢弃。
- 2:通过,调用 MapSubscriber.onNext(2)。
- 3:丢弃。
- 4:通过,调用 MapSubscriber.onNext(4)。
- 5:丢弃。
3.2 MapSubscriber.onNext
MapSubscriber 的 onNext 方法:
kotlin
@Override
public void onNext(T t) {
if (isCancelled()) return;
R v;
try {
v = Objects.requireNonNull(mapper.apply(t), "The mapper returned a null value");
} catch (Throwable ex) {
cancel();
actual.onError(Operators.onOperatorError(this, ex, t, actual.currentContext()));
return;
}
actual.onNext(v);
}
-
t 是从 FilterSubscriber 收到的数据(如 2、4)。
-
mapper 是 n -> n * 10。
-
转换后调用 actual.onNext(v)(actual 是 LambdaSubscriber)。
-
处理过程:
- 2:转换为 20,调用 LambdaSubscriber.onNext(20)。
- 4:转换为 40,调用 LambdaSubscriber.onNext(40)。
3.3 LambdaSubscriber.onNext
LambdaSubscriber 的 onNext 方法:
typescript
@Override
public void onNext(T t) {
if (consumer != null) {
try {
consumer.accept(t);
} catch (Throwable e) {
Operators.onErrorDropped(e, currentContext());
}
}
}
-
t 是从 MapSubscriber 收到的数据(如 20、40)。
-
consumer 是 System.out::println。
-
调用 consumer.accept(t),打印:
- 20
- 40
- 完成信号的传递
数据处理完成后,IterableSubscription 调用 FilterSubscriber.onComplete。
4.1 FilterSubscriber.onComplete
typescript
@Override
public void onComplete() {
if (!isCancelled()) {
actual.onComplete();
}
}
- 调用 MapSubscriber.onComplete。
4.2 MapSubscriber.onComplete
typescript
@Override
public void onComplete() {
if (!isCancelled()) {
actual.onComplete();
}
}
- 调用 LambdaSubscriber.onComplete。
4.3 LambdaSubscriber.onComplete
typescript
@Override
public void onComplete() {
if (completeConsumer != null) {
try {
completeConsumer.run();
} catch (Throwable e) {
Operators.onErrorDropped(e, currentContext());
}
}
}
- completeConsumer 是 null,因此无额外操作。
- 数据流结束。
- 完整链路总结
从 onSubscribe 触发后:
-
Subscription 传递:
- IterableSubscription → FilterSubscriber → MapSubscriber → LambdaSubscriber。
-
request 触发:
- LambdaSubscriber.request(Long.MAX_VALUE) 逐层传递至 IterableSubscription。
-
数据流处理:
- IterableSubscription 发送 [1, 2, 3, 4, 5]。
- FilterSubscriber 过滤出 [2, 4]。
- MapSubscriber 转换为 [20, 40]。
- LambdaSubscriber 打印 20, 40。
-
完成信号:
- IterableSubscription.onComplete 逐层传递至 LambdaSubscriber。
- 为什么这样设计后续链路
- 背压支持:request 从下游到上游传递,控制数据流速率。
- 异步性:每个订阅者可以在不同线程处理(如通过 publishOn),嵌套结构支持线程切换。
- 错误隔离:onError 可在任意层级触发并处理,防止整个链崩溃。