详解SpringBoot 发布ApplicationEventPublisher和监听ApplicationEvent事件

资料地址

Spring @Aync

实现方法

  1. 自定义需要发布的事件类,需要继承ApplicationEvent类或PayloadApplicationEvent<T>(该类也仅仅是对ApplicationEvent的一层封装)
  2. 使用@EventListener来监听事件
  3. 使用ApplicationEventPublisher来发布自定义事件(@Autowired注入即可)
/**
 * 自定义保存事件
 * @author peter
 * 2019/1/27 14:59
 */
public class PersonSaveEvent<DATA> extends ApplicationEvent {
  private DATA data;

  public PersonSaveEvent(DATA source) {
    super(source);
    this.data = source;
  }

  public DATA getData() {
    return data;
  }
}

//发布事件
public void savePerson(Person person){
  personDao.save(person);
  publisher.publishEvent(new PersonSaveEvent<>(1));
}
//监听事件
@EventListener
public void listenEvent(PersonSaveEvent<Integer> event) {
   System.out.println("监听到PersonSaveEvent事件; 接收到的值:" + event.getData() + ";发布的时间为" + Instant.ofEpochMilli(event.getTimestamp()));
}

好处

可以使核心业务与子业务进行解耦,也方便后期的业务的扩展。如新用户注册之后,需要发放优惠券,此时可以在保存用户之后,发布一个新用户的注册成功事件,通过监听该事件来实现发放优惠券的功能。后期新增一个对新用户进行xxx功能,此时可以新写一个监听注册成功事件的监听器,来处理新的业务逻辑,而不需要修改之前的注册逻辑。

注意事项

1、监听器方法中一定要try-catch异常,否则会造成发布事件(有事物的)的方法进行回滚
2、可以使用@Order注解来控制多个监听器的执行顺序,@Order传入的值越小,执行顺序越高
3、对于需要进行事物监听或不想try-catch runtime异常,可以使用@TransactionalEventListener注解

@TransactionalEventListener 监听器

在该注解的源码中:

 * <p>If the event is not published within the boundaries of a managed transaction, the
 * event is discarded unless the {@link #fallbackExecution} flag is explicitly set. If a
 * transaction is running, the event is processed according to its {@code TransactionPhase}.

大意是:如果事件的发布不是在事物(@Transactional)范围内,则监听不到该事件,除非将fallbackExecution标志设置为true(@TransactionalEventListener(fallbackExecution = true));如果在事物中,可以选择在事物的哪个阶段来监听事件,默认在事物提交后监听。

修改监听事物的范围:@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)

在监听器中重新开一个事物

 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
  public void listenEvent1(PersonSaveEvent<Integer> event) {
    divide(event);
  }
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public void divide(PersonSaveEvent<Integer> event) {
    System.out.println("监听到PersonSaveEvent事件; 接收到的值:" + event.getData() + ";接受的时间为" + Instant.ofEpochMilli(event.getTimestamp()));
  }

以上事件都是同步,如果需要异步则需要开启异步支持,在监听器方法加上@Async 注解即可。

/**
 * @author peter
 * @version 1.0
 * @date 2019/04/18 08:47
 */
@Configuration
@EnableAsync
public class AsyncEventConfiguration implements AsyncConfigurer {
  @Override
  public Executor getAsyncExecutor() {
    return Executors.newCachedThreadPool();
  }
}

一旦开始异步执行,方法的异常将不会抛出,只能在方法内部处理。如需在方法外处理异常:Async 异常处理在文章最后

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Spring Boot应用事件监听示例详解

    前言 本文主要给大家介绍了关于Spring Boot应用事件监听的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 1. Spring Boot特有的应用事件 除了Spring框架的事件,Spring Boot的SpringApplication也发送了一些自己的事件: ApplicationStartingEvent:在任何处理(除了注册listener和initializer)开始之前发送. ApplicationEnvironmentPreparedEvent: 在

  • Spring的事件监听机制示例详解

    前言 最近公司在重构广告系统,其中核心的打包功由广告系统调用,即对apk打包的调用和打包完成之后的回调,需要提供相应的接口给广告系统.因此,为了将apk打包的核心流程和对接广告系统的业务解耦,利用了spring的事件监听特性来满足需求.以下说明spring的事件机制的相关内容. 首先spring事件分为事件发布者(EventPublisher).事件监听者(EventListener),还包括一个事件广播者(这个是spring实现相关,这一节不讨论).使用spring事件机制,需要自定义事件发布

  • SpringBoot Application事件监听的实现方案

    先说结论 SpringBoot Application共支持6种事件监听,按顺序分别是: ApplicationStartingEvent:在Spring最开始启动的时候触发 ApplicationEnvironmentPreparedEvent:在Spring已经准备好上下文但是上下文尚未创建的时候触发 ApplicationPreparedEvent:在Bean定义加载之后.刷新上下文之前触发 ApplicationStartedEvent:在刷新上下文之后.调用application命令之

  • 浅谈Spring-boot事件监听

    springboot的事件监听:为bean之间的消息通信提供支持.当一个bean做完一件事以后,通知另一个bean知晓并做出相应处理.这时,我们需要另一个bean,监听当前bean所发生的事件. 实现步骤:四个步骤,四种方式 第一种方式 1.自定义事件,一般是继承ApplicationEvent抽象类 2.定义事件监听器,一般是实现ApplicationListener接口 3.1)把监听器加入到SpringApplication中:ApplicationListener.addListener

  • springboot 事件监听的实现方法

    定义事件 @Getter public class TestEvent extends ApplicationEvent { private String msg; public TestEvent(Object source, String msg) { super(source); this.msg = msg; } } 定义事件监听(注解方式) @Component public class TestListen { @EventListener public void testListe

  • spring boot之SpringApplication 事件监听

    spring application listener 在 spring 框架中,有多种事件, 这些时间会在不同的运行时刻发布,来通知监听者.本文仅仅介绍 SpringApplicationEvent 的事件的监听. 事件类型 EventType 发布时间 ApplicationContextInitializedEvent 在 SpringApplication正在启动, ApplicationContext 已经准备好了,ApplicationContextInitializers 被调用,

  • 详解SpringBoot 发布ApplicationEventPublisher和监听ApplicationEvent事件

    资料地址 Spring @Aync 实现方法 自定义需要发布的事件类,需要继承ApplicationEvent类或PayloadApplicationEvent<T>(该类也仅仅是对ApplicationEvent的一层封装) 使用@EventListener来监听事件 使用ApplicationEventPublisher来发布自定义事件(@Autowired注入即可) /** * 自定义保存事件 * @author peter * 2019/1/27 14:59 */ public cla

  • 详解Apache配置多个监听端口和不同的网站目录

    详解Apache配置多个监听端口和不同的网站目录 一 :添加多端口 Listen 80 Listen 81 Listen 82 二:设置虚拟主机目录 NameVirtualHost *:80 <VirtualHost *:80> ServerName localhost DocumentRoot "D:/phpStudy/WWW/" </VirtualHost> NameVirtualHost *:81 <VirtualHost *:81> Serv

  • 详解RocketMQ 消费端如何监听消息

    目录 前言 流程地图 源码跟踪 核心模块(消息拉取) 拉取流程 拉取消息处理 当pullStatus为FOUND,消息进行提交消费的请求 消息消费进度提交 总结 前言 上一篇文章中我们主要来看RocketMQ消息消费者是如何启动的, 那他有一个步骤是非常重要的,就是启动消息的监听,通过不断的拉取消息,来实现消息的监听,那具体怎么做,让我们我们跟着源码来学习一下~ 流程地图 源码跟踪 这一块的代码比较多,我自己对关键点的一些整理,这个图我画的不是很OK 核心模块(消息拉取) 入口:this.pul

  • 详解SpringCloud eureka服务状态监听

    一.前言 近期由于公司不同平台项目之间的业务整合,需要做到相互访问! 每个平台均有自己的注册中心和服务,且注册中心相互之间并没有相互注册! 借助spring的事件监听,在eureka-server端监听服务注册,将所有服务的ip和port存放至redis库,然后让其他平台服务通过redis库获取ip和端口号,进而进行http调用.结构图如下: 二.事件解析 事件列表 在org.springframework.cloud.netflix.eureka.server.event包下会发现如下类: E

  • 详解vuex结合localstorage动态监听storage的变化

    需求:不同组件间共用同一数据,当一个组件将数据发生变化时,其他组件也可以响应该变化. 分析:vue无法监听localstorage的变化.localstorage主要用于不同页面间传值,vue适合组件间传值.对于组件间共用同一数据又想保存住信息或者再页面刷新的时候不丢失数据(vuex在页面刷新的时候存储的值会丢失,localstorage存储在本地浏览器中),可以采用vuex+localstorage的方式. 关于vuex和storage的区别 1.最重要的区别:vuex存储在内存,locals

  • 详解SpringBoot实现ApplicationEvent事件的监听与发布

    目录 新建SpringBoot项目 实现代码 pom.xml Application.java TaskPoolConfig.java EmailDto.java SendEmailEvent.java SendEmailListener.java SendEmailService.java SendEmailServiceImpl.java IndexController.java 通过发布订阅模式实现数据的异步处理,比如异步处理邮件发送 新建SpringBoot项目 项目结构 .├── po

  • Android ListView监听滑动事件的方法(详解)

    ListView的主要有两种滑动事件监听方法,OnTouchListener和OnScrollListener 1.OnTouchListener OnTouchListener方法来自View中的监听事件,可以在监听三个Action事件发生时通过MotionEvent的getX()方法或getY()方法获取到当前触摸的坐标值,来对用户的滑动方向进行判断,并可在不同的Action状态中做出相应的处理 mListView.setOnTouchListener(new View.OnTouchLis

  • javascript事件监听与事件委托实例详解

    本文实例讲述了javascript事件监听与事件委托.分享给大家供大家参考,具体如下: 事件监听与事件委托 在js中,常用到element.addEventListener()来进行事件的监听.但是当页面中存在大量需要绑定事件的元素时,这种方式可能会带来性能影响.此时,我们可以用事件委托的方式来进行事件的监听. 每个事件都经历三个阶段 捕获 到达目标 冒泡 事件委托需要用到事件的冒泡,冒泡就是事件发生时,上层会一层一层的接收这个事件. 如下页面结构: <body> <div id=&qu

  • vue回到顶部监听滚动事件详解

    本文实例为大家分享了vue回到顶部监听滚动事件,供大家参考,具体内容如下 鼠标滚到到页面中间出现的工具浮框 <template> <div class="tools"> <ul @mouseleave="mouseLeave()"> <li @click="toTop(step)">回到顶部</li> <li @mouseover="mouseOver(1)"&

  • vue使用@scroll监听滚动事件时,@scroll无效问题的解决方法详解

    本文实例讲述了vue使用@scroll监听滚动事件时,@scroll无效问题的解决方法.分享给大家供大家参考,具体如下: 在网上看了一下vue中监听滚动条滚动事件,清一色的使用document.addEventListener('scroll',function(){}) 我是在做滚动条滑到底部时,自动加载更多的时候有这个需求. 我认为使用document.addEventListener会破坏vue的统一性,对我这种有轻微代码强迫症的人来说,让我感觉很不爽.而且这种做法,会让你更加难以判断是否

随机推荐