Java事件链框架(EventChain)

2019-07-16  本文已影响0人  ACap

EventChain是一个纯Java库,写这个库的目的是将复杂的业务拆分成可以独立运行的事件。
然后将他们组合成一条事件链,依次执行链上的事件。

简介
简单使用

先创建一个DemoEvent的事件用来模拟我们的实际业务,这里的业务就是输出一段控制台日志

 public static class DemoEvent extends EventChain {
        String msg;

        public DemoEvent(String msg) {
            this.msg = msg;
        }

        @Override
        protected void call() throws Throwable { //执行具体的业务逻辑
            System.out.println(msg);
            next(); /*事件执行完成,继续下一个事件*/  
        }
    }
 public static void main(String[] args) {
        final DemoEvent e_1 = new DemoEvent("小明:小王,开车了,快上车!");
        final DemoEvent e_2 = new DemoEvent("小王:滴学生卡!");
        final DemoEvent e_3 = new DemoEvent("小明:坐稳,出发了!");

        e_1.chain(e_2).chain(e_3).start(); /*将事件串起来,并顺序执行*/

        /*或者*/
        new DemoEvent("小明:小王,开车了,快上车!")
                .chain(new DemoEvent("小王:滴学生卡!"))
                .chain(new DemoEvent("小明:坐稳,出发了!"))
                .start();
    }

---------------------------------------控制台输出-------------------------------------------
    小明:小王,开车了,快上车!
    小王:滴学生卡!
    小明:坐稳,出发了!
并行事件
 public static void main(String[] args) {
        new DemoEvent("小明:开车了,快上车!")
                .merge( /*并行事件*/
                        new DemoEvent("小王:滴学生卡!"),
                        new DemoEvent("小红:滴学霸卡!")
                      )
                .chain(new DemoEvent("小明:坐稳,出发了!"))
                .start();
    }
---------------------------------------控制台输出-------------------------------------------
    小明:小王,开车了,快上车!
    小王:滴学生卡!
    小红:滴学霸卡!
    小明:坐稳,出发了!

merge()方法中包含的事件是没有先后顺序的,当它们全部执行完成之后才会进入下一个事件,这钟方式常用于多线程编程
merge()中也可以包含另外一条事件链

抛出错误

修改DemoEvent,显示抛出一个异常

public static class DemoEvent extends EventChain {
        String msg;

        public DemoEvent(String msg) {
            this.msg = msg;
        }

        @Override
        protected void call() throws Throwable { /*执行具体的业务逻辑*/
            error(new RuntimeException("抛出错误信息,抛出错误信息之后会中断后续事件"));
            System.out.println(msg);
            next(); /*事件执行成功之后,继续下一个事件*/
        }
    }

//执行
    public static void main(String[] args) {
        new DemoEvent("小明:开车了,快上车!")
                .merge( /*并行事件*/
                        new DemoEvent("小王:滴学生卡!"),
                        new DemoEvent("小红:滴学霸卡!")
                      )
                .chain(new DemoEvent("小明:坐稳,出发了!"))
                .start();
    }
---------------------------------------控制台输出-------------------------------------------
    小明:开车了,快上车!

我们在输出的前面通过error()方法抛出一个异常,导致下面的next()失效,后续的事件将不会再执行
我们调用error()之后没有return,所以还会执行之后的代码
错误日志没有输出?不要着急继续向下看

监听器(OnEventListener与EventChainObserver)

OnEventListener:监听事件的状态
EventChainObserver:监听事件链的状态

    private static class OnDemoEventLisenter implements OnEventListener {

        @Override
        public void onStart() {
            System.err.println("onStart - 事件开始");
        }

        @Override
        public void onError(Throwable e) {
            System.err.println("onError - 出错了:" + e);
        }

        @Override
        public void onNext() {
            System.err.println("onNext - 事件 完成");
        }

        @Override
        public void onComplete() {
            System.err.println("onComplete - 事件链 完成");
        }
    }

执行

    public static void main(String[] args) {
        new DemoEvent("小明:开车了,快上车!") .addOnEventListener(new OnDemoEventLisenter())
                .merge( /*并行事件*/
                        new DemoEvent("小王:滴学生卡!"),
                        new DemoEvent("小红:滴学霸卡!")
                      )
                .chain(new DemoEvent("小明:坐稳,出发了!"))
                .start();
    }
---------------------------------------控制台输出-------------------------------------------
onStart - 事件开始
onError - 出错了:java.lang.RuntimeException: 抛出错误信息,抛出错误信息之后会中断后续事件
onComplete - 事件链 完成
小明:开车了,快上车!

通过监听方法来感知事件的状态,为单个事件设置监听器只能监听单个事件,错误信息已经被EventChain拦截,通过监听器下发出来.
下面删除error()方法,监听事件链的执行

  public static void main(String[] args) {
        EventChain.create(
                new DemoEvent("小明:开车了,快上车!")
                        .merge( /*并行事件*/
                                new DemoEvent("小王:滴学生卡!"),
                                new DemoEvent("小红:滴学霸卡!")
                              )
                        .chain(new DemoEvent("小明:坐稳,出发了!"))
                         )
                .addOnEventListener(new OnDemoEventLisenter())
                .start();
    }
---------------------------------------控制台输出-------------------------------------------
onStart - 事件开始
小明:开车了,快上车!
小王:滴学生卡!
小红:滴学霸卡!
小明:坐稳,出发了!
onNext - 事件 完成
onComplete - 事件链 完成

通过EventChain.create()方法将事件链包装成一个事件,并设置这个事件的监听器,可以监听它包裹的整条事件链 ,或者可以通过EventChainObserver监听事件链

EventChainObserver

创建事件链观察者

    private static class DemoEventChainObserver implements EventChainObserver {

        @Override
        public void onChainStart() {
            System.err.println("onChainStart - 事件链开始");
        }

        @Override
        public void onStart(EventChain event) {
            System.err.println("onStart - 子事件开始:" + event);
        }

        @Override
        public void onError(EventChain event, Throwable e) {
            System.err.println("onError - 子事件开始异常:" + event + "  Throwable:" + e);
        }

        @Override
        public void onNext(EventChain event) {
            System.err.println("onNext - 子事件完成:" + event);
        }

        @Override
        public void onChainComplete() {
            System.err.println("onChainComplete - 事件链 完成");
        }
    }

需要监听某个链的时候,在所有属于该条链的事件设置该监听器

    public static void main(String[] args) {
        new DemoEvent("小明:开车了,快上车!")
                .merge( /*并行事件*/
                        new DemoEvent("小王:滴学生卡!"),
                        new DemoEvent("小红:滴学霸卡!")
                      )
                .chain(new DemoEvent("小明:坐稳,出发了!"))
                .addEventChainObserver(new DemoEventChainObserver())
                .start();
    }
---------------------------------------控制台输出-------------------------------------------
onChainStart - 事件链开始
onStart - 子事件开始:DemoEvent@58372a00 - msg:[小明:开车了,快上车!]
小明:开车了,快上车!
onNext - 子事件完成:DemoEvent@58372a00 - msg:[小明:开车了,快上车!]
onStart - 子事件开始:com.lfp.eventtree.EventMerge@6d03e736 (merge方法包装类)
onStart - 子事件开始:DemoEvent@568db2f2 - msg:[小王:滴学生卡!]
小王:滴学生卡!
onNext - 子事件完成:DemoEvent@568db2f2 - msg:[小王:滴学生卡!]
onStart - 子事件开始:DemoEvent@5fd0d5ae - msg:[小红:滴学霸卡!]
小红:滴学霸卡!
onNext - 子事件完成:DemoEvent@5fd0d5ae - msg:[小红:滴学霸卡!]
onNext - 子事件完成:com.lfp.eventtree.EventMerge@6d03e736 (merge方法包装类)
onStart - 子事件开始:DemoEvent@2d98a335 - msg:[小明:坐稳,出发了!]
小明:坐稳,出发了!
onNext - 子事件完成:DemoEvent@2d98a335 - msg:[小明:坐稳,出发了!]
onChainComplete - 事件链 完成

我们看到本来应该并发执行的事件是串行执行的。这是因为我们所有的事件都在同一线程中执行的。

complete()与interrupt() 事件链的主动中断机制

修改DemoEvent使用complete()方法

    public static class DemoEvent extends EventChain {
        String msg;

        public DemoEvent(String msg) {
            this.msg = msg;
        }

        @Override
        protected void call() throws Throwable { /*执行具体的业务逻辑*/
//            error(new RuntimeException("抛出错误信息,抛出错误信息之后会中断后续事件"));
            System.out.println(msg);

            complete(); //如果同时使用next()方法,complete()必须放在next()之前
            //next(); /*事件执行成功之后,继续下一个事件*/
        }

        @NonNull
        @Override
        public String toString() {
            return getClass().getSimpleName() + "@" 
                      + Integer.toHexString(hashCode()) 
                      + " - msg:[" + msg+"]";
        }
    }

试一试

    public static void main(String[] args) {
        new DemoEvent("小明:开车了,快上车!")
                .merge( /*并行事件 , 由于都在同一线程执行,所以打印出来的效果看起来像的串行*/
                        new DemoEvent("小王:滴学生卡!"),
                        new DemoEvent("小红:滴学霸卡!")
                      )
                .chain(new DemoEvent("小明:坐稳,出发了!"))
                .addEventChainObserver(new DemoEventChainObserver())
                .start();
    }
---------------------------------------控制台输出-------------------------------------------
onChainStart - 事件链开始
onStart - 子事件开始:DemoEvent@58372a00 - msg:[小明:开车了,快上车!]
小明:开车了,快上车!
onChainComplete - 事件链 完成

当调用complete()方法之后将会中断后续的事件,并直接回调事件与事件链的完成方法。
interrupt()方法也是中断事件链的作用,但是他和complete()不同的一点是不会回调事件和事件链的完成方法

添加interrupt()

public static class DemoEvent extends EventChain {
        String msg;

        public DemoEvent(String msg) {
            this.msg = msg;
        }

        @Override
        protected void call() throws Throwable { /*执行具体的业务逻辑*/
//            error(new RuntimeException("抛出错误信息,抛出错误信息之后会中断后续事件"));
            System.out.println(msg);

            interrupt();//如果同时使用next()方法,interrupt()必须放在next()之前
//            complete();//如果同时使用next()方法,complete()必须放在next()之前
            //next(); /*事件执行成功之后,继续下一个事件*/
        }

        @NonNull
        @Override
        public String toString() {
            return getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()) + " - msg:[" + msg+"]";
        }
    }

执行

    public static void main(String[] args) {
        new DemoEvent("小明:开车了,快上车!")
                .merge( /*并行事件 , 由于都在同一线程执行,所以打印出来的效果看起来像的串行*/
                        new DemoEvent("小王:滴学生卡!"),
                        new DemoEvent("小红:滴学霸卡!")
                      )
                .chain(new DemoEvent("小明:坐稳,出发了!"))
                .addEventChainObserver(new DemoEventChainObserver())
                .start();
    }
---------------------------------------控制台输出-------------------------------------------
onChainStart - 事件链开始
onStart - 子事件开始:DemoEvent@58372a00 - msg:[小明:开车了,快上车!]
小明:开车了,快上车!

一个基于EventChain的库 RequestChain

Git地址 EventChain

上一篇下一篇

猜你喜欢

热点阅读