Mono类型解析

java8中的Consumer、Function

Consummer接口

Consumer 是消费者接口,被@FunctionalInterface注解修饰,这意味着它可以看做是一个方法,Consumer接口中定义了一个accept方法。

void accept(T t);

实现Consumer接口的消费者需要重写accept方法,accept方法就是消费生产者生产出来的对象进行消费。Consumer对象可以这样定义:

    Consumer c0 = System.out::println;
    Consumer c1 = x -> System.out.println(x + 1);

Consumer对象可以定义某个对象的方法,或者是类的静态方法,这就是代表 在Consummer的accept方法中使用该对象去执行该方法,或者执行这个类的静态方法。也可以用lambda表达式来进行定义。

Function接口

Function接口也是被@FunctionalInterface注解修饰修饰的,表示一个方法。Function接口中定义了一个apply方法:

    R apply(T t);

与Consumer接口类似,Function接口的实现类需要实现apply方法,通常Function类型的对象作为参数都会去调用Function对象的apply方法,也就是执行这个Function。Function对象也可以按照Consumer接口一样的方式进行定义:

    Function f0 = WebfluxTest::aaa;//这里aaa方法必须是有返回值的静态方法
    Function f1 = (x) -> x + 1;

Function与Consumer的区别就在于,Consumer是没有返回值的,而Function是有返回值的,也因此,如果lambda表达式只有一行,Function中匿名方法中的内容是一个表达式(表示返回的值),而Consumer中匿名方法的内容是一条语句(执行的逻辑)。

Mono和Flux

Mono和Flux都实现了Publisher接口,也就是发布者,一个Mono对象中最多发射一个信号(可能是一个值,或者空,或者一个error),而Flux可以发射多个信号。
Publisher接口中只定义了一个subscribe方法:

public void subscribe(Subscriber s);

subscribe方法就是绑定一个Subscriber去订阅这个Publisher中的信号。
Subscriber类的定义如下:

public interface Subscriber {
    public void onSubscribe(Subscription s);

    public void onNext(T t);

    public void onError(Throwable t);

    public void onComplete();
}

Mono subcribe一个Consummer的过程

首先需要先创建一个Mono对象,Mono提供了一些方法创建Mono对象,如creat,just等:

    public static  Mono just(T data) {
        return onAssembly(new MonoJust<>(data));
    }

    public static  Mono create(Consumer> callback) {
        return onAssembly(new MonoCreate<>(callback));
    }

    public static  Mono defer(Supplier> supplier) {
        return onAssembly(new MonoDefer<>(supplier));
    }

    public static Mono delay(Duration duration, Scheduler timer) {
        return onAssembly(new MonoDelay(duration.toMillis(), TimeUnit.MILLISECONDS, timer));
    }

    public static  Mono empty() {
        return MonoEmpty.instance();
    }

    public static  Mono error(Throwable error) {
        return onAssembly(new MonoError<>(error));
    }

    public static  Mono first(Mono... monos) {
        return onAssembly(new MonoFirst<>(monos));
    }

创建出来的MonoJust,MonoCreate等对象都是Mono的子类,onAssembly方法是将创建好的Mono对象进行装饰增强。MonoJust,MonoCreate这些类都是重写了Mono中的抽象方法:

    public abstract void subscribe(CoreSubscriber actual);

subcribe一个Consummer对象是执行父类Mono中定义的subcribe方法,并一直调用重载的方法,最后将参数构造为一个LambdaMonoSubscriber对象调用subscribeWith方法:

    public final Disposable subscribe(Consumer consumer) {
        Objects.requireNonNull(consumer, "consumer");
        return subscribe(consumer, null, null);
    }

    public final Disposable subscribe(
            @Nullable Consumer consumer,
            @Nullable Consumer errorConsumer,
            @Nullable Runnable completeConsumer) {
        return subscribe(consumer, errorConsumer, completeConsumer, (Context) null);
    }

    public final Disposable subscribe(
            @Nullable Consumer consumer,
            @Nullable Consumer errorConsumer,
            @Nullable Runnable completeConsumer,
            @Nullable Context initialContext) {
        return subscribeWith(new LambdaMonoSubscriber<>(consumer, errorConsumer,
                completeConsumer, null, initialContext));
    }
    
    public final > E subscribeWith(E subscriber) {
        subscribe(subscriber);
        return subscriber;
    }

接着调用Mono类中实现Publisher接口中定义的subscribe方法:

    @Override
    @SuppressWarnings("unchecked")
    public final void subscribe(Subscriber actual) {
        CorePublisher publisher = Operators.onLastAssembly(this);
        CoreSubscriber subscriber = Operators.toCoreSubscriber(actual);

        try {
            //... 省略部分代码
            publisher.subscribe(subscriber);
        }
        catch (Throwable e) {
            Operators.reportThrowInSubscribe(subscriber, e);
            return;
        }
    }

然后调用实现CorePublisher接口中定义的subscribe方法,也是上面提到的需要子类去实现的Mono类中的抽象方法,以MonoJust为例,其实现如下:

    public void subscribe(CoreSubscriber actual) {
        actual.onSubscribe(Operators.scalarSubscription(actual, value));
    }

调用actual的onSubcribe方法,actual就是刚才创建的LambdaMonoSubscriber对象,参数是一个ScalarSubscription类型的对象,其onSubcribe方法如下:

    public final void onSubscribe(Subscription s) {
        if (Operators.validate(subscription, s)) {
            this.subscription = s;

            if (subscriptionConsumer != null) {
                try {
                    subscriptionConsumer.accept(s);
                }
                catch (Throwable t) {
                    Exceptions.throwIfFatal(t);
                    s.cancel();
                    onError(t);
                }
            }
            else {
                s.request(Long.MAX_VALUE);
            }

        }
    }

如果有异常会调用Subscription对象的cancel方法和LambdaMonoSubscriber对象自身的onError方法,否则会调用Subscription对象的request方法,这里的Subscription对象的实际类型为ScalarSubscription类型,其request方法如下:

        public void request(long n) {
            if (validate(n)) {
                if (ONCE.compareAndSet(this, 0, 1)) {
                    Subscriber a = actual;
                    a.onNext(value);
                    if(once != 2) {
                        a.onComplete();
                    }
                }
            }
        }

request方法中汇调用LambdaMonoSubscriber对象的onNext方法和onComplete方法

基于以上的源码,可以总结如下:

  • Mono提供了一些方法创建Mono对象(MonoCreate,MonoJust等),这些对象都是Publisher
  • Publisher可以subcribe Subcriber,subcribe过程就是构造一个Subcription,然后作为参数执行Subcriber的onSubcribe方法,如果有异常就执行Subscription的cancel方法和自身的onError方法
  • Subcriber的onSubcribe方法中执行Subcription的request方法,request方法里面会执行Subcriber的onNext方法和onComplete方法
  • Mono对象可以直接subcribe一个Consumer对象,其实是把这个consummer变成一个Subcriber对象

你可能感兴趣的:(Mono类型解析)