SpringBoot 异步事件实现异步(ApplicationEventPublisher、ApplicationEvent)_springboot applicationevent 异步-程序员宅基地

技术标签: spring  java  异步事件  ApplicationEventPublisher  ApplicationEvent  springboot  

SpringBoot 异步事件实现异步(ApplicationEventPublisher、ApplicationEvent)

​ 当把一个事件发布到Spring提供的ApplicationContext中,被监听器侦测到,就会执行对应的处理方法。

实现步骤:

  • 自定义发布的事件类,需要继承 ApplicationEvent 或者PayloadApplicationEvent(该类也仅仅是对ApplicationEvent的一层封装)
  • 监听事件 使用注解 @EventListener 或者 自定义监听器在主函数添加监听器
  • s使用ApplicationEventPublisher 或者 实现其接口的子类 发布自定义事件 (@Autowired注入即可)

一、事件本身 ApplicationEvent

事件是一个自定义的类,需要继承Spring提供的ApplicationEvent

import com.alibaba.fastjson.JSONObject;
import org.springframework.context.ApplicationEvent;

/**
 * 自定义 事件
 * @author 王泽华
 * 2019/10/22 14:59
 */
public class EsSaveEvent extends ApplicationEvent {
    

    private JSONObject data;

    public EsSaveEvent(JSONObject source) {
    
        super(source);
        this.data = source;
    }

    public JSONObject getData() {
    
        return data;
    }
}

二、事件监听

1、自定义监听器

​ 基本方法是实现ApplicationListener接口,自定义一个监听器,实现onApplicationEvent()方法,然后添加到ApplicationContext

import org.springframework.context.ApplicationListener;

public class MyListener implements ApplicationListener<EsSaveEvent> {
    

    @Override  
    public void onApplicationEvent(EsSaveEvent event) {
    
        //事件处理
        System.out.print("监听到MyEvent事件");  
    }  
}

注意:需要在springboot 启动类添加监听器,如下所示:

public static void main(String[] args) {
    
    SpringApplication application = new SpringApplication(MyApplication.class);
    SpringBoot的启动类中添加监听器
    application.addListeners(new MyListener());
    application.run(args);
 }

2、使用注解@EventListener(推荐):

​ 原理就是通过扫描这个注解,创建监听器并添加到ApplicationContext

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

/**
 * @author :王泽华
 * @Title: EventListener
 * @date 2019/10/2214:18
 */
@Component
public class EventListener {
    

    //监听事件
    @org.springframework.context.event.EventListener
    public void listenEvent(EsSaveEvent  event) {
    
        //可以添加事务处理
        //divide(event);
        JSONObject object = event.getData();
        //对数据进行处理
         System.out.println("data:"+object.toJSONString());
        }

    }

    //在监听器中重新开一个事务(可选)
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void divide(EsSaveEvent event) {
    
        System.out.println("事务处理");
    }


}

三、事件发布

事件发布可以用springboot内部类 也可以自定义

1、直接注入 ApplicationEventPublisher

​ 使用 ApplicationEventPublisher,注入ApplicationEventPublisher接口,调用publisher.publishEvent(new EsSaveEvent(data)) 发布事件。

@Autowired
private ApplicationEventPublisher publisher;

public test(){
    
	JSONObject data=new JSONObject();
    publisher.publishEvent(new EsSaveEvent(data));
}

2、自定义事件发布类(继承ApplicationEventPublisher)

A、实现 ApplicationEventPublisher

import com.alibaba.fastjson.JSONObject;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

@Component
public class EventService implements ApplicationEventPublisherAware {
        
    public ApplicationEventPublisher publisher;    
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
    
        this.publisher = applicationEventPublisher;
    }
    public String doEventWork(String msg) {
    
        JSONObject data=new JSONObject();
        data.put("message","------------publish event:" + msg);
        EsSaveEvent event = new EsSaveEvent(data);
        publisher.publishEvent(event);
        return "OK";
    }
}

B、测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class EventServiceTest {
    
    @Autowired
    private EventService service;
    @Test
    public void eventTest() {
    
        String msg="Java Code";
        service.doEventWork(msg);
    }
}

四、注意事项:

1、如果2个事件之间是继承关系,会先监听到子类事件,处理完再监听父类。

2、监听器方法一定要try-catchy异常,否则会造成发布事件(有事务的)的方法进行回滚

3、可以使用@Order注解控制多个监听器的执行顺序,@Order 传入的值越小,执行顺序越高

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/gu_zhou/article/details/102686856

智能推荐

国内计算机论文期刊,国内都有哪些计算机领域的投稿期刊-程序员宅基地

文章浏览阅读1.2k次。国内都有哪些计算机领域的投稿期刊发布时间:2019-01-14 15:11浏览: 次计算机在各行各业都得到了广泛的应用,而这一方向的从业人员也越来越多,他们也是可以评定计算机工程师职称的,但也需要发表计算机方向的论文,最近就有作者咨询我们的老师,关于国内计算机领域的投稿期刊,小编在此介绍:计算机专业领域的刊物有很多,也分计算机在各行各业都得到了广泛的应用,而这一方向的从业人员也越来越多,他们也是可..._计算机专业普刊

计算机设备管理使用实施细则,办公电脑及相关设备管理工作细则.doc-程序员宅基地

文章浏览阅读286次。乌蒙科技制度编号:E3055KY制度页数:共12页办公电脑及相关设备管理细则编 制 人:审 核 人:批 准 人:主办单位:总经理室公布日期:20XX年12月30日生效日期:20XX年 1 月 1日第一章 总 则目标为规范办公电脑及相关设备使用、维护、维修,依据集团[办公电脑及相关设备管理措施]之要求制订本细则。适用范围本细则适适用于矿业本部及所属子企业办公电脑及相关设备管理。办公电脑及相关设备分...

python数据结构与算法分析_Python数据结构与算法--算法分析-程序员宅基地

文章浏览阅读202次。在计算机科学中,算法分析(Analysis of algorithm)是分析执行一个给定算法需要消耗的计算资源数量(例如计算时间,存储器使用等)的过程。算法的效率或复杂度在理论上表示为一个函数。其定义域是输入数据的长度,值域通常是执行步骤数量(时间复杂度)或者存储器位置数量(空间复杂度)。算法分析是计算复杂度理论的重要组成部分。一个有趣的问题经常出现,那就是两个看似不同的程序,到底哪个更好呢?要回..._energy+=list1[a]*list1[a-1]*list1[(a+1)%(n-i)]

linux6.4发送日志,RHEL6.4 搭建 Rsyslog 日志服务 Rsyslog+MySQL+Loganalyzer-程序员宅基地

文章浏览阅读67次。rsyslog 建立:安装rsyslog服务包,rsyslog-mysql的rpm包需要装上去,是日志和数据库结合的包配置/etc/rsyslog.conf文件vi/etc/rsyslog.confSYSLOGD_OPTIONS="-c2-r-x-m180" ##添加,KLOGD_OPTIONS="-x" ##添加,$ModLoadimm...

android的drawrect透明图层,android – 在活动上创建一个黑色透明的图层-程序员宅基地

文章浏览阅读279次。以编程方式,您可以使用Canvas创建图层.用你的颜色填充整个东西并切出一个洞.public class DrawView extends View {Paint paint = new Paint();Paint transparentPaint = new Paint;public DrawView(Context context) {super(context);}@Overridepubl..._canvas drawrect 全透明

NLP练习之RNN,使用pytorch_pytorch nlp 例子“”-程序员宅基地

文章浏览阅读251次。import numpy as npimport torchimport torch.nn as nnimport torch.optim as optimfrom torch.autograd import Variabledtype = torch.FloatTensorsentences = [ "i like dog", "i love coffee", "i hate milk"]word_list = " ".join(sentences).split()word_list_pytorch nlp 例子“”

随便推点

linux smartctl 命令,Smartctl 命令查看硬盘详细信息-程序员宅基地

文章浏览阅读6.1k次。Smartctl命令查看硬盘详细信息(2011-08-30 14:21:41)标签:linux硬盘信息使用时间杂谈1.1什么是Smartmontools?Smartmontools是一种硬盘检测工具,通过控制和管理硬盘的SMART(Self Monitoring Analysis andReportingTechnology,自动检测分析及报告技术)技术来实现的,SMART技术可以对硬盘的磁头单..._smartctl查看硬盘信息

压力传感器实例编程与java,如何使用Arduino进行编程 通通过压力传感器控制电机转速...-程序员宅基地

文章浏览阅读804次。/** circuits4you.com* 2016 November 25* Load Cell HX711 Module Interface with Arduino to measure weight in KgsArduinopin2 -> HX711 CLK3 -> DOUT5V -> VCCGND -> GNDMost any pin on the Arduin...

python 数据恢复 编程_Python | 数据恢复实验室 Data Recovery Laboratory-程序员宅基地

文章浏览阅读1.1k次。最近使用Python为项目开发一款绘图工具(绘出 声场三维模型)。因为希望能把Python脚本发布为脱离Python平台运行的可执行程序,比如单个的exe文件。PyInstaller恰满足这个需求。本文PyInstaller的版本是2.0,支持Python2.7。下面讨论怎样安装,使用PyInstaller。PyInstaller本身并不属于Python包。在安装 pyinstaller 之前假设..._python恢复硬盘数据 csdn

windows服务器上无法运行bat文件,ad域用户bat脚本运行不了-程序员宅基地

文章浏览阅读1.8k次。发表于2017-2-22 10:20|来自51CTO网页引用:原帖由 wankily 于 2017-2-22 08:33 发表 域环境是server2008,做了一个bat脚本,内容很简单,echo %date%,%username%,%COMPUTERNAME% >>\\192.168.10.1\tools$\pc-imformation-collect.txt,就是收集一下域..._windows sever .bat文件无法运行

既然android service是运行在主线程中的,那service还有什么用?_每个线程都有一个messagequeue-程序员宅基地

文章浏览阅读4.9k次,点赞2次,收藏6次。既然android service是运行在主线程中的,那service还有什么用?对于Android,每一个进程都有一个主线程,四大组件的处理任务都是在这个线程中进行的。每个线程都有一个MessageQueue,里面用于存放Message,四大组件的处理工作是用Message来封装的。可以说Android应用层是消息驱动的。你的想法可能是,Service长期在后台工作,如果它是运行在主线程中的..._每个线程都有一个messagequeue

关于HTML5你需要了解的基础知识-程序员宅基地

文章浏览阅读75次。HTML5 是第五个且是当前的 HTML 版本,它是用于在万维网上构建和呈现内容的标记语言。本文将帮助读者了解它。HTML5 通过 W3C 和Web 超文本应用技术工作组Web Hypertext Application Technology Working Group之间的合作发展起来。它是一个更高版本的 HTML,它的许多新元素可以使你的页...