spring上下文的异步Event事件

Easter79
• 阅读 668

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

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

spring上下文的异步Event事件

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

实现流程一般为:

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

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

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

代码如下:

/**
 * 下单事件
 * 
 * @author lennon
 *
 */
public class OrderCreateEvent extends ApplicationEvent{

    private static final long serialVersionUID = 1L;
    
    private String orderSn;

    public OrderCreateEvent(String orderSn) {
        super(SpringContextHolder.getApplicationContext());
        this.orderSn = orderSn;
    }

    public String getOrderSn() {
        return orderSn;
    }

    public void setOrderSn(String orderSn) {
        this.orderSn = orderSn;
    }
}

/**
 * 下单事件监听器
 * 
 * @author lennon
 *
 */
@Component
@Async
public class OrderCreateEventListener implements ApplicationListener<OrderCreateEvent> {

    @Override
    public void onApplicationEvent(OrderCreateEvent orderCreateEvent) {
        // 对下单操作进行处理
        System.out.println("打印订单");
        System.out.println(orderCreateEvent.getOrderSn());
    }

}

/**
 * 下单成功之后发布异步事件
 * 
 * @author lennon
 *
 */
public class OrderCreateEventPublisher {

    
    public void afterCreateOrder() {
        
        // 下单
        OrderCreateEvent orderCreateEvent = new OrderCreateEvent(UUID.randomUUID().toString());
        
        // ....
        // 下单成功
        System.out.println("下单成功之后,异步做一些简单处理");
        
        
        SpringContextHolder.getApplicationContext().publishEvent(orderCreateEvent);
        
        System.out.println("异步之后!");
    }
}

/**
 * 持有spring的上下文对象
 * 
 * @author lennon
 *
 */
@Component
public class SpringContextHolder implements ApplicationContextAware{

    private static ApplicationContext applicationContext = null;  
      
    @Override  
    public void setApplicationContext(ApplicationContext applicationContext)  
            throws BeansException {  
        this.applicationContext = applicationContext;  
    }  
      
    public static Object getBean(String name){  
        return applicationContext.getBean(name);  
    }
    
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}

总结:

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

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

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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
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
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
kenx kenx
3年前
SpringBoot异步使用@Async原理及线程池配置
前言在实际项目开发中很多业务场景需要使用异步去完成,比如消息通知,日志记录,等非常常用的都可以通过异步去执行,提高效率,那么在Spring框架中应该如何去使用异步呢使用步骤完成异步操作一般有两种,消息队列MQ,和线程池处理ThreadPoolExecutor而在Spring4中提供的对ThreadPoolExecutor封装的线程池ThreadPoolTa
Wesley13 Wesley13
3年前
MQ应用场景
MQ常见应用场景以下介绍消息队列在实际应用中常用的使用场景。异步处理,应用解耦,流量削锋,日志处理和消息通讯四个场景。异步处理场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种1.串行的方式;2.并行方式。(1)串行方式:将注册信息写入数据库(https://www.oschina.net/ac
Stella981 Stella981
3年前
Linux网络IO模型
同步和异步,阻塞和非阻塞_同步和异步_关注的是结果消息的通信机制同步:同步的意思就是调用方需要主动等待结果的返回异步:异步的意思就是不需要主动等待结果的返回,而是通过其他手段比如,状态通知,回调函数等。_阻塞和非阻塞_主要关注的是等待结果返回调用方的状态阻塞:是指
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
Noark入门之异步事件
引入异步事件主要是为了各模块的解耦,每当完成一个动作时,向系统发布一个事件,由关心的模块自己监听处理,可选择同步处理,异步处理,延迟处理。何时发布事件,当其他模块关心此动作时<br比如获得道具时,任务系统模块要判定完成进度,BI模块需要上报等等都可以监听此事件,已达模块解耦0x00事件源一个实现xyz.noark.core.event
专为小白打造—Kafka一篇文章从入门到入土 | 京东云技术团队
一、什么是KafkaMQ消息队列作为最常用的中间件之一,其主要特性有:解耦、异步、限流/削峰。Kafka和传统的消息系统(也称作消息中间件)都具备系统解耦、冗余存储、流量削峰、缓冲、异步通信、扩展性、可恢复性等功能。与此同时,Kafka还提供了大多数消息系
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k