spring上下文的异步Event事件

在实际开发中,我们经常会需要做一件事:在完成某一个动作之后,需要另外以同步或者异步的方式去通知另外的对象去完成额外的操作,比如:当用户下单成功之后,需要发异步消息到给到邮件系统发邮件(短信)通知用户。(这里就涉及到异步消息的概念)

消息队列是我们用来解决系统与系统之间异步与解耦的极佳实践工具,而在应用内部这个级别上,有时候也会需要这样的异步消息通知机制。

spring提供的事件通知机制是基于在容器内部注册与监听的模式,本质上是Observer模式(观察者模式)。对于不明白观察者模式或者忘记的,可以百度了解一下。其实在jdk中也有对观察者模式做了实现,有兴趣的读者也可以了解一下。事件发布注册早容器中(事件注册中心),由事件注册中心去通知相应的监听器去处理该事件。

实现流程一般为:

1、定义扩展自ApplicationEvent类的事件。

2、定义实现自ApplicationListener接口的监听器。

3、通过上下文环境进行事件发布。

代码如下:

1/** 2 * 下单事件 3 * 4 * @author lennon 5 * 6 */ 7public class OrderCreateEvent extends ApplicationEvent{ 8 9 private static final long serialVersionUID = 1L; 10 11 private String orderSn; 12 13 public OrderCreateEvent(String orderSn) { 14 super(SpringContextHolder.getApplicationContext()); 15 this.orderSn = orderSn; 16 } 17 18 public String getOrderSn() { 19 return orderSn; 20 } 21 22 public void setOrderSn(String orderSn) { 23 this.orderSn = orderSn; 24 } 25} 26 27/** 28 * 下单事件监听器 29 * 30 * @author lennon 31 * 32 */ 33@Component 34@Async 35public class OrderCreateEventListener implements ApplicationListener<OrderCreateEvent> { 36 37 @Override 38 public void onApplicationEvent(OrderCreateEvent orderCreateEvent) { 39 // 对下单操作进行处理 40 System.out.println("打印订单"); 41 System.out.println(orderCreateEvent.getOrderSn()); 42 } 43 44} 45 46/** 47 * 下单成功之后发布异步事件 48 * 49 * @author lennon 50 * 51 */ 52public class OrderCreateEventPublisher { 53 54 55 public void afterCreateOrder() { 56 57 // 下单 58 OrderCreateEvent orderCreateEvent = new OrderCreateEvent(UUID.randomUUID().toString()); 59 60 // .... 61 // 下单成功 62 System.out.println("下单成功之后,异步做一些简单处理"); 63 64 65 SpringContextHolder.getApplicationContext().publishEvent(orderCreateEvent); 66 67 System.out.println("异步之后!"); 68 } 69} 70 71/** 72 * 持有spring的上下文对象 73 * 74 * @author lennon 75 * 76 */ 77@Component 78public class SpringContextHolder implements ApplicationContextAware{ 79 80 private static ApplicationContext applicationContext = null; 81 82 @Override 83 public void setApplicationContext(ApplicationContext applicationContext) 84 throws BeansException { 85 this.applicationContext = applicationContext; 86 } 87 88 public static Object getBean(String name){ 89 return applicationContext.getBean(name); 90 } 91 92 public static ApplicationContext getApplicationContext() { 93 return applicationContext; 94 } 95}

总结:

1、异步Event事件与自定义线程实现,到底哪种好?什么时候要用异步事件,什么时候使用线程?

2、什么时候使用异步Event,什么时候使用同步Event?

3、深入了解底层的观察者模式,如何自己写出一套基于发布与订阅的异步Event事件框架?【值得尝试做一下,重复造轮子可以检验自己的能力】

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

SpringBoot异步使用@Async原理及线程池配置

前言在实际项目开发中很多业务场景需要使用异步去完成,比如消息通知,日志记录,等非常常用的都可以通过异步去执行,提高效率,那么在Spring框架中应该如何去使用异步呢使用步骤完成异步操作一般有两种,消息队列MQ,和线程池处理ThreadPoolExecutor而在Spring4中提供的对ThreadPoolExecutor封装的线程池ThreadPoolTa

MQ应用场景

MQ常见应用场景以下介绍消息队列在实际应用中常用的使用场景。异步处理,应用解耦,流量削锋,日志处理和消息通讯四个场景。异步处理场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种1.串行的方式;2.并行方式。(1)串行方式:将注册信息写入数据库(https://www.oschina.net/ac

Linux网络IO模型

同步和异步,阻塞和非阻塞_同步和异步_关注的是结果消息的通信机制同步:同步的意思就是调用方需要主动等待结果的返回异步:异步的意思就是不需要主动等待结果的返回,而是通过其他手段比如,状态通知,回调函数等。_阻塞和非阻塞_主要关注的是等待结果返回调用方的状态阻塞:是指