ApplicationListener系列文章
上一篇文章,属于基础版ApplicationListener基础版,我们正常的业务使用,但是还有一些缺陷:
- 同一个数据的增删改,需要建立对应的操作事件。
- 没有提取公共部分,例如:Listener的互相影响问题,存在一个Listener出现异常,影响其他Listener的消费。
ApplicationListener进阶版
数据抽象
public class BaseSource implements Serializable {
private String sourceType;
public BaseSource(String sourceType) {
this.sourceType = sourceType;
}
/**
* 数据类型
* 监听者根据类型,进行判断是否处理。
* 类似MQ中的tag
*
* @return 数据类型
*/
public String getSourceType() {
return sourceType;
}
public boolean isDeleteOperate() {
return EventSourceOperation.DELETE.getOperate().equals(getSourceType());
}
public boolean isAddOperate() {
return EventSourceOperation.ADD.getOperate().equals(getSourceType());
}
public boolean isEditOperate() {
return EventSourceOperation.EDIT.getOperate().equals(getSourceType());
}
}
/**操作类型枚举*/
public enum EventSourceOperation {
ADD("ADD", "新增"),
EDIT("EDIT", "修改"),
DELETE("DELETE", "删除");
private final String operate;
private final String desc;
EventSourceOperation(String operate, String desc) {
this.operate = operate;
this.desc = desc;
}
public String getOperate() {
return operate;
}
}
事件抽象
抽象出BaseEvent,主要作用:
- 添加业务属性name。
- 解决ApplicationEvent获取Source时,返回Object,通过泛型解决Listener的类型转换。
public class BaseEvent<S extends BaseSource> extends ApplicationEvent {
private String name;
public BaseEvent(S s) {
this("", s);
}
public BaseEvent(String name, S s) {
super(s);
this.name = name;
}
@Override
public S getSource() {
return (S) super.getSource();
}
public String getName() {
return name;
}
}
监听抽象
接口抽象
抽取公共接口,规定了监听需要具有的通用接口,让监听更完善。
public interface IEventListener<E extends BaseEvent> extends ApplicationListener<E> {
/**
* 是否支持,根据需要判断是否进行下一步
*
* @param event 事件
* @return true=支持
*/
boolean support(E event);
/**
* 处理事件,建议自行try catch
*
* @param event 事件
*/
void handleEvent(E event);
/**
* 处理异常,如果没有try catch,会自动捕捉并包装异常
*
* @param event 事件
* @param eventHandleException 事件处理过程中,出现的异常
*/
void handleException(E event, EventHandleException eventHandleException);
}
基础实现
基础监听,实现IEventListener,同时对事件与数据进行剥离,原因:监听器,其实核心关心的是事件带有的数据,因此提供:BaseEventSourceListener,监听只需要关心Source即可。类似于:MQ消息,关心的不是消息,而是消息承载的内容。
public abstract class BaseEventSourceListener<E extends BaseEvent<S>, S extends BaseSource> implements IEventListener<E> {
@Override
public boolean support(E event) {
return supportSource(event.getSource());
}
/**
* 子类重写,是否支持事件中的数据,
* 类似于:MQ中的tag判断,通过一个事件,承载不同处理的数据。
*
* @param source 数据
* @return true=支持该数据
*/
public abstract boolean supportSource(S source);
@Override
public void handleEvent(E event) {
handleSource(event.getSource());
}
/**
* 处理该事件的核心数据
*
* @param source 事件的核心:数据
*/
public abstract void handleSource(S source);
/**
* 默认处理方式:
* 包装异常,同时抛出特殊异常
* */
@Override
public void handleException(E event, EventHandleException eventHandleException) {
throw eventHandleException;
}
@Override
public void onApplicationEvent(E event) {
if (support(event)) {
//try catch的必要性,当多个Listener监听同一个事件时,防止监听之间的互相影响
try {
handleEvent(event);
} catch (Exception e) {
handleException(event, new EventHandleException(e));
}
}
}
}
示例监听
用户新增的监听
public class UserAddChangeListener extends BaseEventSourceListener<UserChangeEvent, UserChange> {
@Override
public boolean supportSource(UserChange source) {
return source.isAddOperate();
}
@Override
public void handleSource(UserChange source) {
System.out.println("user change add:" + source.toString());
}
}
用户删除的监听
public class UserDeleteChangeListener extends BaseEventSourceListener<UserChangeEvent, UserChange> {
@Override
public boolean supportSource(UserChange source) {
return source.isDeleteOperate();
}
@Override
public void handleSource(UserChange source) {
System.out.println("user change delete:" + source.toString());
}
}
发布事件
public static void main(String[] args) throws InterruptedException {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(UserAddChangeListener.class);
applicationContext.register(UserDeleteChangeListener.class);
applicationContext.refresh();
applicationContext.publishEvent(new UserChangeEvent(UserChange.createAddOperation(1, "userAdd ")));
applicationContext.publishEvent(new UserChangeEvent(UserChange.createDeleteOperation(1, "userDelete ")));
}
结果输出
user change add:UserChange(id=1, name=userAdd )
user change delete:UserChange(id=1, name=userDelete )