美文网首页
Java事件链框架(EventChain)

Java事件链框架(EventChain)

作者: ACap | 来源:发表于2019-07-16 18:04 被阅读0次

    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 - 事件链 完成");
            }
        }
    
    

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

    • 在这之前我优化了DemoEvent中的toString方法用于明确打印的对象
        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

    相关文章

      网友评论

          本文标题:Java事件链框架(EventChain)

          本文链接:https://www.haomeiwen.com/subject/bkltlctx.html