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
网友评论