使用Spring事件机制实现异步的方法
作者:Joepis 发布时间:2023-06-23 06:47:08
标签:Spring,事件机制,异步
当把一个事件发布到Spring提供的ApplicationContext中,被 * 侦测到,就会执行对应的处理方法。
事件本身
事件是一个自定义的类,需要继承Spring提供的ApplicationEvent
。
@Data
public class MyEvent extends ApplicationEvent {
private String msg;
public MyEvent(Object source, String msg) {
super(source);
this.msg = msg;
}
}
事件监听
基本方法是实现ApplicationListener
接口,自定义一个 * ,实现onApplicationEvent()
方法,然后添加到ApplicationContext
。
比如:
public class MyListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
System.out.print("监听到MyEvent事件");
}
}
...
// SpringBoot的启动类中添加 *
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.addListeners(new MyListener());
application.run(args);
}
也可以使用注解@EventListener
(推荐):原理就是通过扫描这个注解,创建 * 并添加到ApplicationContext
。
@Component
@Slf4j
public class MyEventHandler {
@EventListener
public void handleEvent(MyEvent event) {
log.info("------------处理事件:{}", event.getMsg());
try {
Thread.sleep(5 * 1000L);
log.info("事件1(5s)处理完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
事件发布
可以通过上下文对象的发布方法ConfigurableApplicationContext::publishEvent()
来发布。
也可以实现ApplicationEventPublisherAware
接口来发布(推荐)。
@Component
@Slf4j
public class EventService implements ApplicationEventPublisherAware {
public ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
public String doEventWork(String msg) {
log.info("------------publish event:" + msg);
MyEvent event = new MyEvent(this, msg);
publisher.publishEvent(event);
return "OK";
}
}
测试代码
@SpringBootTest
@RunWith(SpringRunner.class)
public class EventServiceTest {
@Autowired
private EventService service;
@Test
public void eventTest() {
String msg="Java Code";
service.doEventWork(msg);
}
}
注意
如果2个事件之间是继承关系,会先监听到子类事件,处理完再监听父类。
// MyEvent2 extends MyEvent
@Component
@Slf4j
public class MyEventHandler {
@EventListener
public void handleEvent(MyEvent event) {
log.info("------------处理事件:{}", event.getMsg());
try {
Thread.sleep(5 * 1000L);
log.info("事件1(5s)处理完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@EventListener
public void handleEvent2(MyEvent2 event) {
log.info("------------处理事件2:{}", event.getMsg());
try {
Thread.sleep(10 * 1000L);
log.info("事件2(10s)处理完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
当我publish一个子类事件MyEvent2时,日志如下:
来源:https://www.jianshu.com/p/47ae0bbdf205


猜你喜欢
- 一:本文使用范围此文不仅仅局限于spring boot,普通的spring工程,甚至是servlet工程,都是一样的,只不过配置一些 * 的
- Android的遮罩效果就是把一张图片盖在另一张图片的上面,通过控制任意一张图片的显示百分比实现遮罩效果。下面我使用两张一样的图片来实现一个
- Invoke Phing targets这个插件主要是读取xml形式包括自动化测试打包部署的配置文件,然后根据流程走下来。用ph
- 上一篇博文《Android中Handler使用浅析》通过实现倒计时闪屏页面的制作引出了Handler的使用方法以及实现原理,博文末尾也提到了
- mybatis在持久层框架中还是比较火的,一般项目都是基于ssm。虽然mybatis可以直接在xml中通过SQL语句操作数据库,很是灵活。但
- list stream: reduce的使用stream 中的 reduce 的主要作用就是stream中元素进行组合,组合的方式可以是加减
- 本文实例为大家分享了AndAndroid实现网页图片浏览的具体代码,供大家参考,具体内容如下基本功能:输入图片的url然后点击按钮加载出来图
- 这篇文章主要介绍了Spring @Transactional注解失效解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的
- java多线程-同步块Java 同步块(synchronized block)用来标记方法或者代码块是同步的。Java 同步块用来避免竞争。
- 前言这段时间比较闲,就看起了jdk源码。一般的一个高级开发工程师, 能阅读一些源码对自己的提升还是蛮大的。本文总结了一些JDK源码中的“小技
- 要获取Java中的当前时间戳:Timestamp timestamp = new Timestamp(System.currentTimeM
- 目录 任务和线程的区别: 一、认识Task和Task的基本使用1、认识Task2、创建Task 二、Task的
- 本文实例讲述了Android操作SQLite数据库(增、删、改、查、分页等)及ListView显示数据的方法。分享给大家供大家参考,具体如下
- public static string GetMD5(string sDataIn) &nb
- 以下是测试代码:新建一个classlibrary,包含两个类class1和class2,这两个类中分别有一个方法,都是返回一个字符串,代码如
- 1.网关简介所谓的网关就是指系统的统一入口,它封装了运用程序的内部结构,为客户端提供统一的服务,一些与业务功能无关的公共逻辑可以在这里实现,
- package com.wanmei.meishu;import java.io.FileInputStream;import java.i
- 基础知识介绍: @RequestBody主要用来接收前端传递给后端的json字符串中的
- 线上出现了如上的 crash,第一解决反应是在 show dialog 之前做个 isFinish 和 isDestroyed 判断,当我翻
- 本文实例讲述了Java获得当前时间前指定几个小时具体时间的方法。分享给大家供大家参考,具体如下:package getBeforeHourD