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 super T> 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 extends Mono extends T>> 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 extends T>... monos) {
return onAssembly(new MonoFirst<>(monos));
}
创建出来的MonoJust,MonoCreate等对象都是Mono的子类,onAssembly方法是将创建好的Mono对象进行装饰增强。MonoJust,MonoCreate这些类都是重写了Mono中的抽象方法:
public abstract void subscribe(CoreSubscriber super T> actual);
subcribe一个Consummer对象是执行父类Mono中定义的subcribe方法,并一直调用重载的方法,最后将参数构造为一个LambdaMonoSubscriber对象调用subscribeWith方法:
public final Disposable subscribe(Consumer super T> consumer) {
Objects.requireNonNull(consumer, "consumer");
return subscribe(consumer, null, null);
}
public final Disposable subscribe(
@Nullable Consumer super T> consumer,
@Nullable Consumer super Throwable> errorConsumer,
@Nullable Runnable completeConsumer) {
return subscribe(consumer, errorConsumer, completeConsumer, (Context) null);
}
public final Disposable subscribe(
@Nullable Consumer super T> consumer,
@Nullable Consumer super Throwable> 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 super T> 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 super T> 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 super T> 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对象