【观察者模式】publishevent 事件监听
注:文章皆为个人纪录,可用性请以最终结果为准,若有错还请大佬们指出,谢谢!
使用场景: 在业务流程处理中,经常需要做业务的解耦,比方说在注册功能中,只关心注册的主流程,而注册成功后会做发放积分券之类的副流程,副流程业务也属于注册的一部分,此时就需要将注册的主流程与发放积分券的副流程进行解耦。 注意: 事件监听处理在代码中为同步的串行执行,不要理解为异步处理,目的只是为了进行 业务的解耦与代码的解耦
步骤一:定义事件
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)); }