注:文章皆为个人纪录,可用性请以最终结果为准,若有错还请大佬们指出,谢谢!
使用场景:
在业务流程处理中,经常需要做业务的解耦,比方说在注册功能中,只关心注册的主流程,而注册成功后会做发放积分券之类的副流程,副流程业务也属于注册的一部分,此时就需要将注册的主流程与发放积分券的副流程进行解耦。
注意:
事件监听处理在代码中为同步的串行执行,不要理解为异步处理,目的只是为了进行
业务的解耦与代码的解耦
步骤一:定义事件
1.1 定义事件的基类(MyBaseEvent )
事件核心为继承 ApplicationEvent 类
public class MyBaseEvent extends ApplicationEvent {
protected static final Logger LOGGER = LoggerFactory.getLogger(MyBaseEvent.class);
public MyBaseEvent(Object source) {
super(source);
}
public MyBaseEvent(Object source, Clock clock) {
super(source, clock);
}
}
1.2 定义具体的事件对象
public class DisburseSuccessEvent extends MyBaseEvent {
public Disbursement disbursement; // 监听的对象
public DisburseSuccessEvent(Object source, Disbursement disbursement) {
super(source);
this.setDisbursement(disbursement);
}
public void setDisbursement(Disbursement disbursement) {
this.disbursement = disbursement;
}
public Disbursement getDisbursement() {
return disbursement;
}
}
步骤二:定义监听器并绑定事件对象
监听器核心为在方法上添加@EventListener注解或者实现ApplicationListener接口
@Component
@Order(1) // 使用order指定顺序,越小优先级越高
public class DisburseSuccessListener {
@EventListener(DisburseSuccessEvent.class) // 绑定事件对象
public void onApplicationEvent(DisburseSuccessEvent disburseSuccessEvent) {
// TODO 副流程业务的同步处理,若需异步处理,则需要自行引入MQ
}
}
步骤三:封装监听方法
核心为 ApplicationContext 对象 以及 实现 ApplicationContextAware 接口
@Component
public class SpringContextBean implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if(SpringContextBean.applicationContext == null){
SpringContextBean.applicationContext = applicationContext;
}
}
/** 获取applicationContext */
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
步骤四:调用示例
核心为用监听方法调用 publishEvent 触发事件监听
@Override
public String registered (CoinsApiResultStatusParam param) {
// 注册流程
System.out.println("注册成功");
// 触发事件监听副流程业务
SpringContextBean.getApplicationContext().publishEvent(new DisburseSuccessEvent(this, disbursement));
}