Java Flow API 的实践(二):Publisher的简单封装
概述
从前一篇文章中可以看到,使用 Publisher 的其中一种方式就是直接写一个类实现 Publisher 接口,在该类中实现对应的业务逻辑。不过按照这种方式实现,对于一些临时性的功能会产生大量一次性的类。一种解决方式就是像RxJava的创建操作符那样,将实际操作过程抽象出去。本文就按照后一种方式来封装。
实现效果如下:
Flow.Publisher<Integer> publisher;
/* 1.从数组创建 */
publisher = Flows.fromArray(new Integer[]{1, 2, 3, 4});
/* 2.从可迭代集合创建 */
publisher = Flows.fromIterable(Arrays.asList(1, 2, 3));
/* 3.从Callable创建 */
publisher = Flows.fromCallable(() -> 1);
/* 4.从可变参数创建 */
publisher = Flows.from(1, 2, 3);
/* 5.通过Emitter实现 */
publisher = Flows.create(emitter -> {
try {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
});
publisher.subscribe(new Flow.Subscriber<Integer>() {
@Override
public void onSubscribe(Flow.Subscription subscription) {
System.out.println("ExampleUnitTest.onSubscribe =>");
}
@Override
public void onNext(Integer item) {
System.out.println("ExampleUnitTest.onNext =>" + item);
}
@Override
public void onError(Throwable throwable) {
System.out.println("ExampleUnitTest.onError =>" + throwable);
}
@Override
public void onComplete() {
System.out.println("ExampleUnitTest.onComplete =>");
}
});
类之间关系如下:
Emitter接口和实现
定义一个Emitter接口,实现 Subscription 和 Subscriber 接口,并新增一个 isCanceled 方法用于判断是否被取消,如下:
public interface Emitter<T> extends Flow.Subscription, Flow.Subscriber<T> {
boolean isCanceled();
}
实现如下:
class EmitterImpl<R> implements Emitter<R> {
private volatile boolean isCanceled = false;
private Flow.Subscriber<? super R> subscriber;
EmitterImpl(Flow.Subscriber<? super R> subscriber) {
this.subscriber = Objects.requireNonNull(subscriber);
}
@Override
public void onSubscribe(Flow.Subscription subscription) {
if (subscriber != null)
subscriber.onSubscribe(subscription);
}
@Override
public void onNext(R item) {
if (subscriber != null)
subscriber.onNext(item);
}
@Override
public void onError(Throwable throwable) {
if (subscriber != null)
subscriber.onError(throwable);
}
@Override
public void onComplete() {
if (subscriber != null) {
subscriber.onComplete();
subscriber = null;
}
}
@Override
public void request(long n) {
}
@Override
public void cancel() {
isCanceled = true;
subscriber = null;
}
@Override
public boolean isCanceled() {
return isCanceled;
}
}
Publisher的实现
EmitterPublisher使用Emitter承接实际的操作和订阅者,如下:
public class EmitterPublisher<T> implements Flow.Publisher<T> {
private final Consumer<Emitter<T>> source;
public EmitterPublisher(Consumer<Emitter<T>> source) {
this.source = Objects.requireNonNull(source);
}
@Override
public void subscribe(Flow.Subscriber<? super T> subscriber) {
EmitterImpl<T> emitter = new EmitterImpl<>(Objects.requireNonNull(subscriber));
emitter.onSubscribe(emitter);
source.accept(emitter);
}
}
Flows 工具类
提供一个工具类来方便使用:
public final class Flows {
public static <T> Flow.Publisher<T> just(T item) {
return from(item);
}
public static <T> Flow.Publisher<T> from(T... items) {
return fromArray(items);
}
public static <T> Flow.Publisher<T> fromIterable(Iterable<T> iterable) {
return new EmitterPublisher<>(emitter -> {
try {
for (T t : iterable) {
emitter.onNext(t);
}
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
});
}
public static <T> Flow.Publisher<T> fromArray(T[] tArray) {
return new EmitterPublisher<>(emitter -> {
try {
for (T t : tArray) {
emitter.onNext(t);
}
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
});
}
public static <T> Flow.Publisher<T> fromCallable(final Callable<T> callable) {
return create(tEmitter -> {
try {
tEmitter.onNext(callable.call());
tEmitter.onComplete();
} catch (Exception e) {
tEmitter.onError(e);
}
});
}
public static Flow.Publisher<Void> fromAction(final Runnable runnable) {
return create(voidEmitter -> {
try {
runnable.run();
voidEmitter.onComplete();
} catch (Exception e) {
voidEmitter.onError(e);
}
});
}
public static <T> Flow.Publisher<T> create(Consumer<EmitterPublisher.Emitter<T>> source) {
return new EmitterPublisher<>(source);
}
}