Spring5中Reactor编程的Mono与Flux类源码解读

Spring5的函数式编程使用了ProjectReactor工程的类,使用最为多的就是Mono和Flux类型,其中Mono是针对0到1个元素进行操作,Flux是针对多个元素进行操作。要使用这两个类前提是自己要有jdk8,Lambda,函数式编程的基础,否则请先学习了以上知识再来接触Spring5的Mono和FLux。

我们针对Mono类的一行代码,来进行源码分析与讲解。代码如下:

Mono.just("hello").subscribe(System.out::println);
这行代码是生成有一个元素的Mono类,并打印“hello”字符串。

 

首先,通过Mono.just()方法生成了Mono类
    public static <T> Mono<T> just(T data) {
        return onAssembly(new MonoJust<>(data));
    }
以上代码可以看到是创建了一个MonoJust类型,这个类和Mono,FLux类型一样在reactor-core包中,其实Mono的每个方法都会对应生成一个Mono的子类,其子类很多,如下:

 

截图只是列举了一部分,Mono采用这种每个方法都生成一个类的方式是与jdk8中的Stream流水线的最大区别,目的是为了重用任意阶段的结果,且其所有子类都实现了Mono类的方法:

public abstract void subscribe(CoreSubscriber<? super T> actual);

这个方法我们后面会讲,它的作用就是处理后面的函数式的逻辑。

 

 

在返回MonoJust类型后,我们调用了subscribe(System.out::println)方法,这个方法在Mono类有具体实现,方法如下:
    public final Disposable subscribe(Consumer<? super T> consumer) {
        Objects.requireNonNull(consumer, "consumer");
        return subscribe(consumer, null, null);
    }
这个方法是所有Mono的子类执行subscribe(CoreSubscriber<? super T> actual)方法的入口,我们进入看下,执行到了如下方法:

 

    public final Disposable subscribe(
            @Nullable Consumer<? super T> consumer,
            @Nullable Consumer<? super Throwable> errorConsumer,
            @Nullable Runnable completeConsumer,
            @Nullable Consumer<? super Subscription> subscriptionConsumer) {
        return subscribeWith(new LambdaMonoSubscriber<>(consumer, errorConsumer,
                completeConsumer, subscriptionConsumer));
    }
我们看到有四个参数,根据字面意思即可理解,lambda表达式是第一个参数consumer,可以看到执行Lambda的方法时候创建了一个类型LambdaMonoSubscriber,这个类型封装了封装了四个参数。

 

后面进入此方法:

    @Override
    public final void subscribe(Subscriber<? super T> actual) {
        onLastAssembly(this).subscribe(Operators.toCoreSubscriber(actual));
    }
这个方法是重写了父类Publisher的suscribe方法,我们看到代码做了类型转换,通过类型转换就转换为了可以调用MonoJust中的subscribe方法了,MonoJust总的subscribe方法如下,所有的Mono子类都重写了此方法:

    @Override
    public void subscribe(CoreSubscriber<? super T> actual) {
        actual.onSubscribe(Operators.scalarSubscription(actual, value));
    }
然后通过LambdaMonoSubscriber的onSubscribe方法在调用Operators的request方法,再调用此LambdaMonoSubscriber的onNext方法,最后调用了我们自己写的Lambda表达式,如下:
    @Override
    public final void onNext(T x) {
        Subscription s = S.getAndSet(this, Operators.cancelledSubscription());
        if (s == Operators.cancelledSubscription()) {
            Operators.onNextDropped(x, Context.empty());
            return;
        }
        if (consumer != null) {
            try {
                consumer.accept(x);
            }
consumer就是我们传入进来的Lambda表达式,这个方法继承自Suscriber类

通过这种方式,Publisher发送的subscribe就被Subscriber类消费掉了。其实全程都是一个单线程的操作。借鉴了消费订阅模式。

 

关于Mono的方法很多,在此只是举了一个简单的例子,其他的方法也可以通过类似的方式去研究。

在此处有一篇比较好的介绍Reactor编程的文章
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值