spring @EventListener 事件与监听的示例详解

 更新时间:2025年03月05日 11:38:17   作者:xixingzhe2  
本文介绍了自定义Spring事件和监听器的方法,包括如何发布事件、监听事件以及如何处理异步事件,通过示例代码和日志,展示了事件的顺序执行和异步处理机制,感兴趣的朋友一起看看吧

1、自定义Application Event

package com.ybw.event.pojo;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;
/**
 * @className MyEvent
 * @author weixiansheng
 * @date 2023/9/28 
 * @version V1.0
 **/
@Setter
@Getter
public class MyEvent extends ApplicationEvent {
    private String data;
    public MyEvent(Object source, String data) {
        super(source);
        this.data = data;
    }
}

2、自定义监听

package com.ybw.event.listener;
import com.ybw.event.pojo.MyEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
 * 简单监听
 *
 * @author weixiansheng
 * @version V1.0
 * @className MySimpleListener
 * @date 2023/9/28
 **/
@Component
@Slf4j
public class MySimpleListener {
    /**
     * @param event
     * @methodName: handleDemoEvent
     * @return: void
     * @author: weixiansheng
     * @date: 2023/9/28
     **/
    @EventListener
    public void handleDemoEvent(MyEvent event) {
        log.info("发布的data为:{}", event.getData());
    }
}

3、测试

package com.ybw.event.listener;
import com.ybw.event.pojo.MyEvent;
import com.ybw.util.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.concurrent.TimeUnit;
/**
 * @author weixiansheng
 * @version V1.0
 * @className MySimpleListenerTest
 * @date 2023/9/28
 **/
@SpringBootTest
@Slf4j
class MySimpleListenerTest {
    /**
     * 发布消息
     *
     * @methodName: publishEvent
     * @return: void
     * @author: weixiansheng
     * @date: 2023/9/28
     **/
    @Test
    public void publishEvent() throws InterruptedException {
        log.info("publishEvent start");
        SpringContextHolder.publishEvent(new MyEvent(this, "测试"));
        log.info("publishEvent end");
        TimeUnit.DAYS.sleep(1);
    }
}

打印日志

[INFO ] 2023-09-28 10:19:15.312 [main] c.y.e.listener.MySimpleListenerTest - publishEvent start
[INFO ] 2023-09-28 10:19:16.344 [main] c.y.event.listener.MySimpleListener - 发布的data为:测试
[INFO ] 2023-09-28 10:19:16.347 [main] c.y.e.listener.MySimpleListenerTest - publishEvent end

4、源代码

share: 分享仓库 - Gitee.com

5、其他

5.1 顺序执行

使用注解

  • @Order order的值越小,优先级越高。
  • order如果不标注数字,默认最低优先级,因为其默认值是int最大值。

示例

/**
 * 普通监听
 *
 * @param event
 * @methodName: handleDemoEvent
 * @return: void
 * @author: weixiansheng
 * @date: 2023/9/28
 **/
@EventListener
@Order(2)
public void handleEvent(MyEvent event) throws InterruptedException {
    TimeUnit.SECONDS.sleep(1);
    log.info("handleEvent data:{}", event.getData());
}
/**
 * 条件监听
 *
 * @param event
 * @methodName: handleConditionEvent
 * @return: void
 * @author: weixiansheng
 * @date: 2023/9/28
 **/
@EventListener(condition = "#event.data=='张三'")
@Order(1)
public void handleConditionEvent(MyEvent event) {
    log.info("handleConditionEvent data:{}", event.getData());
}

打印日志

[INFO ] 2023-09-28 10:40:22.206 [main] c.y.event.listener.MySimpleListener - handleConditionEvent data:张三
[INFO ] 2023-09-28 10:40:23.216 [main] c.y.event.listener.MySimpleListener - handleEvent data:张三

 5.2 异步支持

        Spring 事件机制默认是同步阻塞的,如果 ApplicationEventPublisher 发布事件之后他会一直阻塞等待listener 响应,多个 listener 的情况下前面的没有执行完后面的会一直被阻塞。发布者和订阅者属于同一事务,如果订阅者执行失败了,发布者事务会回滚。

        可以利用 Spring 提供的线程池注解 @Async 来实现异步线程。异步不影响发布者的事务。

示例

/**
 * 普通监听
 *
 * @param event
 * @methodName: handleDemoEvent
 * @return: void
 * @author: weixiansheng
 * @date: 2023/9/28
 **/
@EventListener
public void handleEvent(MyEvent event) throws InterruptedException {
    TimeUnit.SECONDS.sleep(1);
    log.info("handleEvent data:{}", event.getData());
}
/**
 * 条件监听
 *
 * @param event
 * @methodName: handleConditionEvent
 * @return: void
 * @author: weixiansheng
 * @date: 2023/9/28
 **/
@Async
@EventListener(condition = "#event.data=='张三'")
public void handleConditionEvent(MyEvent event) {
    log.info("handleConditionEvent data:{}", event.getData());
}

打印日志

[INFO ] 2023-09-28 10:49:40.246 [thread-pool-1] com.ybw.event.listener.MyListener - handleConditionEvent data:张三
[INFO ] 2023-09-28 10:49:41.255 [main] com.ybw.event.listener.MyListener - handleEvent data:张三

一个是线程thread-pool-1,一个是线程main。 

6、总结

  • 事件模式概念
    • 事件:事件的触发者,比如用户注册就是事件。
    • 事件发布:描述发生了什么事情的对象,比如张三注册成功的事件。
    • 事件监听:监听到事件发生的时候,做一些处理,比如下单后,增加用户积分。
  • Spring中事件监听器的处理是同步方式
    • 日志都是都一个线程。
    • 执行时顺序的,执行完监听器的业务后,会向下继续执行后面的逻辑。如上例:publishEvent end。

到此这篇关于spring @EventListener 事件与监听的文章就介绍到这了,更多相关spring @EventListener 事件与监听内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringCloud中Zuul网关原理及其配置

    SpringCloud中Zuul网关原理及其配置

    Spring Cloud是一个基于Spring Boot实现的微服务应用开发工具,其中的Zuul网关可以实现负载均衡、路由转发、鉴权、限流等功能,本文将从Spring Cloud中Zuul网关的原理、使用场景和配置过程详细介绍,帮助大家更好地了解和应用Zuul网关,需要的朋友可以参考下
    2023-06-06
  • 详解mybatis @SelectProvider 注解

    详解mybatis @SelectProvider 注解

    这篇文章主要介绍了mybatis @SelectProvider 注解的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-12-12
  • SpringBoot yml配置敏感信息加密的实现

    SpringBoot yml配置敏感信息加密的实现

    本文主要介绍了SpringBoot yml配置敏感信息加密的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-08-08
  • Java中的锁分类的详细介绍

    Java中的锁分类的详细介绍

    这篇文章主要介绍了Java中的锁分类的详细介绍,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Spring事务事件监控的实现

    Spring事务事件监控的实现

    这篇文章主要介绍了Spring事务事件监控的实现。本文首先会使用实例进行讲解Spring事务事件是如何使用的,然后会讲解这种使用方式的实现原理。感兴趣的小伙伴们可以参考一下
    2018-10-10
  • Java的字符读写类CharArrayReader和CharArrayWriter使用示例

    Java的字符读写类CharArrayReader和CharArrayWriter使用示例

    这篇文章主要介绍了Java的字符读写类CharArrayReader和CharArrayWriter使用示例,两个类分别继承于Reader和Writer,需要的朋友可以参考下
    2016-06-06
  • JavaAgent原理及实践分享

    JavaAgent原理及实践分享

    这篇文章主要介绍了JavaAgent原理及实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • java poi sax方式处理大数据量excel文件

    java poi sax方式处理大数据量excel文件

    这篇文章主要介绍了java poi sax方式处理大数据量excel文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • SpringBoot实现热部署的三种方式

    SpringBoot实现热部署的三种方式

    本文主要介绍了SpringBoot实现热部署的三种方式,主要包括配置pom.xml文件,使用插件的执行命令mvn spring-boot:run启动项,使用springloader本地启动修改jvm参数,使用devtools工具包,感兴趣的可以了解一下
    2023-12-12
  • 基于Vue.js和Ant Design Vue实现根据字段内容动态设置表格颜色功能

    基于Vue.js和Ant Design Vue实现根据字段内容动态设置表格颜色功能

    在前端开发中,表格Table是展示数据的常见组件,有时,我们需要根据表格中某些字段的内容动态设置样式,例如根据百分比数值显示不同的颜色,以提升数据的可读性和用户体验,本文将详细介绍如何基于Vue.js和Ant Design Vue实现这一功能,并结合实际代码示例进行解析
    2025-06-06

最新评论