webflux 中 flux 的代码是怎么实现的

Flux 是 Spring WebFlux 中的核心类型之一,它的实现遵循 Reactive Streams 规范,基于 Publisher-Subscriber 模式,并结合了异步、非阻塞和背压机制。接下来我们从代码实现层面深入剖析 Flux 是如何实现的。

1. Flux 继承结构

在代码层面,Flux 继承了 Mono,并且实现了 Publisher 接口。MonoFlux 是响应式编程的基本构建块:

  • Mono<T>:表示一个异步产生零或一个元素的数据流。
  • Flux<T>:表示一个异步产生零或多个元素的数据流。
public final class Flux<T> extends FluxSource<T> implements Publisher<T> {
    // Flux 是 Publisher 的一种实现
}
  • FluxSource<T>Flux 的基础类,封装了流的具体实现。
  • Flux 实现了 Publisher<T>,因此,它是响应式流的生产者。

2. Flux 和 Publisher 接口

Flux 实现了 Reactive Streams 规范中的 Publisher 接口,Publisher 接口定义了 subscribe 方法。通过这个方法,订阅者 (Subscriber) 可以订阅数据流。订阅后,数据流才会被启动,Flux 开始将数据推送给订阅者。

public interface Publisher<T> {
    void subscribe(Subscriber<? super T> s);
}

Flux 中,subscribe() 方法的实现是启动数据流的入口,下面是它的基本实现:

@Override
public void subscribe(Subscriber<? super T> s) {
    // 创建 Subscription,并将其传递给 Subscriber
    FluxSubscriber<T> fluxSubscriber = new FluxSubscriber<>(s);
    s.onSubscribe(fluxSubscriber);
    // 调用底层流的订阅方法来启动数据流
    source.subscribe(fluxSubscriber);
}

这里,FluxSubscriberSubscriber 的实现,负责将流的结果传递给订阅者,控制数据的消费过程。

3. Flux 数据流的处理

Flux 的实现利用了 惰性求值链式操作 来处理数据流。每个操作符(如 mapfilter)都生成一个新的 Flux 对象,这个新对象包含了对原始流的变换操作。

示例:map 操作符实现

当我们调用 map() 操作符时,实际上是对 Flux 进行了转换。map() 返回的是一个新的 Flux 对象,这个对象包含了将每个元素映射为新值的逻辑。

public final class Flux<T> {
    public <R> Flux<R> map(Function<? super T, ? extends R> transformer) {
        // 创建一个新的 Flux,封装转换操作
        return new FluxMap<>(this, transformer);
    }
}

FluxMap 是一个新的 Flux 实现类,它封装了 map 操作符的具体实现:

public final class FluxMap<T, R> extends Flux<R> {
    private final Flux<? extends T> source;
    private final Function<? super T, ? extends R> transformer;

    public FluxMap(Flux<? extends T> source, Function<? super T, ? extends R> transformer) {
        this.source = source;
        this.transformer = transformer;
    }

    @Override
    public void subscribe(Subscriber<? super R> s) {
        // 在订阅时,应用转换逻辑
        source.subscribe(new FluxMapSubscriber<>(s, transformer));
    }
}

FluxMapSubscriberSubscriber 的实现,它在 onNext() 方法中进行转换,并将结果传递给原始订阅者。

public class FluxMapSubscriber<T, R> implements Subscriber<T> {
    private final Subscriber<? super R> actual;
    private final Function<? super T, ? extends R> transformer;

    public FluxMapSubscriber(Subscriber<? super R> actual, Function<? super T, ? extends R> transformer) {
        this.actual = actual;
        this.transformer = transformer;
    }

    @Override
    public void onNext(T t) {
        // 将元素应用转换函数
        R transformed = transformer.apply(t);
        actual.onNext(transformed);
    }
    
    @Override
    public void onComplete() {
        actual.onComplete();
    }
    
    @Override
    public void onError(Throwable t) {
        actual.onError(t);
    }
}

4. 背压机制的实现

背压(Backpressure)是 Reactive Streams 规范的重要组成部分,它通过 Subscription 对象实现。Subscription 负责管理消费者与生产者之间的数据流量,确保当消费者处理不过来时,生产者不会继续发送数据。

关键代码:Subscription 相关

Fluxsubscribe() 方法内部创建 FluxSubscriber 时,会向 Subscriber 注册 Subscription

public final class Flux<T> implements Publisher<T> {
    @Override
    public void subscribe(Subscriber<? super T> s) {
        FluxSubscriber<T> fluxSubscriber = new FluxSubscriber<>(s);
        s.onSubscribe(fluxSubscriber);
        source.subscribe(fluxSubscriber);
    }
}

FluxSubscriber 在收到数据时,会根据 request() 方法的调用来控制流量。背压的关键实现就在于 onSubscribe() 中的 request()

public class FluxSubscriber<T> implements Subscriber<T>, Subscription {
    private final Subscriber<? super T> actual;
    
    public FluxSubscriber(Subscriber<? super T> actual) {
        this.actual = actual;
    }

    @Override
    public void onSubscribe(Subscription subscription) {
        // 接收到订阅时,通知订阅者请求数据
        this.subscription = subscription;
        actual.onSubscribe(this);
    }

    @Override
    public void request(long n) {
        // 请求n个元素,确保生产者不会无限制地发出元素
        subscription.request(n);
    }

    @Override
    public void cancel() {
        subscription.cancel();
    }
}

5. 线程调度与非阻塞

Flux 中的非阻塞和异步执行是通过 Scheduler 来实现的。Spring WebFlux 提供了多种调度策略,例如 subscribeOn()publishOn(),通过这些方法可以控制数据流的执行线程。

public final class Flux<T> {
    public Flux<T> subscribeOn(Scheduler scheduler) {
        return new FluxSubscribeOn<>(this, scheduler);
    }
    
    public Flux<T> publishOn(Scheduler scheduler) {
        return new FluxPublishOn<>(this, scheduler);
    }
}
  • subscribeOn(Scheduler scheduler) 用于指定数据流的订阅操作在哪个线程上执行。
  • publishOn(Scheduler scheduler) 用于指定后续操作(如 map, filter 等)在哪个线程池中执行。

这两个方法分别通过 FluxSubscribeOnFluxPublishOn 来实现。

6. 总结

Flux 的实现本质上是基于 Reactive Streams 规范的一个响应式数据流框架。它利用了 Publisher-Subscriber 模式背压机制 来处理异步流,保证了系统在高并发场景下的高效性和可扩展性。

  • Flux 通过 subscribe() 方法启动数据流。
  • 操作符(如 mapfilter 等)通过返回新的 Flux 对象来进行数据流的转换。
  • 背压机制通过 Subscription 实现,控制数据流速。
  • Scheduler 用于管理线程池,确保异步非阻塞执行。

这些设计确保了 Flux 能够高效、灵活地处理异步数据流,适应各种高并发和高负载的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值