Java Flow API 的实践(二):Publisher的简单封装

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 =>");
    }
});

类之间关系如下:
实现的UML描述

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);
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Flow APIJava SE 9 中引入的一种新的编程模型,用于异步控制流程。以下是一个简单Java Flow API 示例: ```java import java.util.concurrent.Flow.*; import java.util.concurrent.SubmissionPublisher; public class FlowAPIExample { public static void main(String[] args) throws InterruptedException { // 创建一个发布者 SubmissionPublisher<String> publisher = new SubmissionPublisher<>(); // 创建一个订阅者 Subscriber<String> subscriber = new Subscriber<String>() { private Subscription subscription; @Override public void onSubscribe(Subscription subscription) { this.subscription = subscription; subscription.request(1); } @Override public void onNext(String item) { System.out.println("Received item: " + item); subscription.request(1); } @Override public void onError(Throwable throwable) { throwable.printStackTrace(); } @Override public void onComplete() { System.out.println("Subscription complete"); } }; // 订阅发布者 publisher.subscribe(subscriber); // 发送数据 publisher.submit("Hello"); publisher.submit("World"); // 关闭发布者 publisher.close(); // 等待订阅者处理完所有数据 Thread.sleep(1000); } } ``` 在这个示例中,我们创建了一个发布者和一个订阅者。订阅者实现了 Subscriber 接口,并在其中定义了如何处理接收到的数据。当订阅者订阅了发布者后,发布者会向订阅者发送数据。在这个示例中,我们向发布者提交了两个字符串,即 "Hello" 和 "World"。当所有数据都被处理完后,发布者会关闭,并通知订阅者。在这里,我们使用 Thread.sleep() 方法等待订阅者处理完所有数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值