Spring事件驱动

这篇具有很好参考价值的文章主要介绍了Spring事件驱动。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        本文主要介绍在Spring环境中,如何使用事件机制。

 一、快速上手

        首先借助org.springframework.context.ApplicationEventPublisher#publishEvent(org.springframework.context.ApplicationEvent)来发布事件,而接收方,则在直接处理的方法上,添加@EventListener注解即可。

1. 事件定义

发布一个事件,所以第一件事要做的就是定义一个事件,对于Spring而言,要求自定义的事件继承一个ApplicationEvent类,一个简单的demo如下:

public class NotifyEvent extends ApplicationEvent {
    @Getter
    private String msg;

    public NotifyEvent(Object source, String msg) {
        super(source);
        this.msg = msg;
    }

}

2. 发布事件

发布事件则比较简单,直接拿到ApplicationContext实例,执行publish方法即可,如下给出一个简单的发布类:

@Component
public class NotifyPublisher implements ApplicationContextAware {

    private ApplicationContext apc;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.apc = applicationContext;
    }

    public void publishEvent(String msg){
        apc.publishEvent(new NotifyEvent(this, msg)); 
    }
}

3. 事件监听器

在方法上添加注释即可,如下

@Component
public class NotifyQueueListener {

    @EventListener
    public void consumerA(NotifyEvent notifyEvent){

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("A: "  + Thread.currentThread().getName()+ "|" + notifyEvent.getMsg());
    }

    

   
}

二、疑问与解答

1.发布与监听器的关联

        上面给出了快速入门,看起来并不复杂,也比较容易使用,但是有一个问题需要在使用之前弄明白了,发布事件和监听器是怎样关联起来的呢?

那么如果发布者,推送的是一个NotifyEvent类型的事件,那么接收者是怎样的呢?

  • 根据方法参数类型执行
  • 参数为NotifyEvent以及其子类的监听器,都可以接收到消息

测试用例如下:

NewNotifyEvent 继承自上面的NotifyEvent

public class NewNotifyEvent extends NotifyEvent {
    @Getter
    private int version;

    public NewNotifyEvent(Object source, String msg) {
        super(source, msg);
    }
    public NewNotifyEvent(Object source, String msg, int version) {
        super(source, msg);
        this.version = version;
    }
}

发布事件修改如下:

@Component
public class NotifyPublisher implements ApplicationContextAware {

    private ApplicationContext apc;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.apc = applicationContext;
    }

    public void publishEvent(int status, String msg){
        if (status == 0){
            apc.publishEvent(new NotifyEvent(this, msg));
        }else {
            apc.publishEvent(new NewNotifyEvent(this, msg , (int) (System.currentTimeMillis()/1000)));
        }

    }
}

 事件监听修改如下:

@Component
public class NotifyQueueListener {

    @EventListener
    public void consumerA(NotifyEvent notifyEvent){

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("A: "  + Thread.currentThread().getName()+ "|" + notifyEvent.getMsg());
    }

    @EventListener
    public void consumerB(NewNotifyEvent newNotifyEvent){

        System.out.println("B: "  + Thread.currentThread().getName()+ "|" + newNotifyEvent.getMsg());
    }

    @EventListener
    public void consumerC(NotifyEvent notifyEvent){

        System.out.println("C: "  + Thread.currentThread().getName()+ "|" + notifyEvent.getMsg());
    }

   
}

测试代码

@RunWith(SpringRunner.class)
@SpringBootTest
@EnableAutoConfiguration
public class EventTest {

    @Autowired
    private NotifyPublisher notifyPublisher;
    @Test
    public void testPublishEvent(){
        notifyPublisher.publishEvent(1,"新的发布事件! NewNotify");
        System.out.println("---------");
        notifyPublisher.publishEvent(0,"旧的发布事件! Notify");
    }

}

输出结果如下,对于NewNotifyEvent, 参数类型为NotifyEvent的consumerA, consumerC都可以接收到

A: main|新的发布事件! NewNotify
C: main|新的发布事件! NewNotify
B: main|新的发布事件! NewNotify
---------
A: main|旧的发布事件! Notify
C: main|旧的发布事件! Notify

2. 消息接收的顺序

上面消息处理是串行的,那么先后顺序怎么确定? (下面的答案不确定,有待深入源码验证!!!)

  • 先扫描到的bean先处理
  • 同一个bean中,按精确匹配,先后定义顺序进行

3. 异步消费

对于异步消费,即在消费者方法上添加一个@Async注解,并需要在配置文件中,开启异步支持

@Async
@EventListener
public void processNewNotifyEvent(NewNotifyEvent newNotifyEvent) {
    System.out.println("new notifyevent: " + newNotifyEvent.getMsg() + " : " + newNotifyEvent.getVersion());
}

配置支持

@Configuration
@EnableAsync
public class AysncListenerConfig implements AsyncConfigurer {
    /**
     * 获取异步线程池执行对象
     * @return
     */
    @Override
    public Executor getAsyncExecutor() {
        return new ThreadPoolExecutor(5,5,1, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>());
    }
    }
}

执行结果如下:

A: main|新的发布事件! NewNotify
C: main|新的发布事件! NewNotify
B: main|新的发布事件! NewNotify
pool-1-thread-1 new notifyevent: 新的发布事件! NewNotify : 1688383517
---------
A: main|旧的发布事件! Notify
C: main|旧的发布事件! Notify

参考传送门:

180609-Spring之事件驱动机制的简单使用 - 一灰灰Blog文章来源地址https://www.toymoban.com/news/detail-555832.html

到了这里,关于Spring事件驱动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVA后端开发面试基础知识(八)——Spring

    Spring是一个轻量级Java开发框架 我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发,比如说 Spring 支持 IoC(Inverse of Control:控制反转) 和 AOP(Aspect-Oriented Programming:面向切面编程)、可以很方便地对数据库进行访问、

    2024年03月10日
    浏览(72)
  • 微信小程序的授权登录-Java 后端 (Spring boot)

    微信开发文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 一个可以测试的微信小程序 此微信小程序的APPID和APPscret(至开发者后台获取) 从时序图我们可以了解到流程大致分为两步: 小程序端获取code后传给Java后台 Java后台获取code后向微信后台接口

    2024年02月09日
    浏览(53)
  • “从零开始学习Spring Boot:快速搭建Java后端开发环境“

    标题:从零开始学习Spring Boot:快速搭建Java后端开发环境 摘要:本文将介绍如何从零开始学习Spring Boot,并详细讲解如何快速搭建Java后端开发环境。通过本文的指导,您将能够快速搭建一个基于Spring Boot的Java后端开发环境并开始编写代码。 正文: 一、准备工作 在开始之前,

    2024年02月15日
    浏览(55)
  • Java-Spring Boot 集成海康威视明眸门禁 布防|报警|回调|获取事件|查询用户信息

    最近做门禁的集成,突然感觉海康这个东西挺有意思的,于是记录一下。 好了废话不多说,开始上环境、代码 本集成是海康-设备网络集成(以人为中心) 环境:windows 开发工具:IDEA JDK版本:JDK-11.0.12 海康jar包:怎么引入都行(本地引入、maven上传到私服)           

    2024年04月15日
    浏览(123)
  • 2023 最新版IntelliJ IDEA 2023.1创建Java Web前(vue3)后端(spring-boot3)分离 项目详细步骤(图文详解)

    2023 最新版IntelliJ IDEA 2023.1创建Java Web 项目详细步骤(图文详解) 本篇使用当前Java Web开发主流的spring-boot3框架来创建一个Java前后端分离的项目,前端使用的也是目前前端主流的vue3进行一个简单的项目搭建,让你距离Java全栈开发更近一步 🏴‍☠️。 使用版本: “17.0.1”

    2024年02月12日
    浏览(85)
  • 【Spring源码】Spring Event事件

    目录 1、前言 2、什么是Spring Event? 3、基本使用 3.1、定义事件 3.2、发布事件 3.3、监听事件 3.3.1、继承ApplicationListener 3.3.2、使用@EventListener注解 4、Spring Event是同步还是异步? 4.1、源码实现 4.2、如何实现异步 4.2.1、使用@Async注解 4.2.2、手动实现异步线程池 4.2.3、自定义Appli

    2024年02月04日
    浏览(35)
  • 从源码Debug深入spring事件机制,基于观察者模式仿写spring事件监听骨架

    定义一个事件 定义两个listener 注入spring容器里的ApplicationEventPublisher对象,发布事件 从 eventPublisher.publishEvent(new MyEvent(\\\"xxx\\\")); 进去很容易就能找到,可以发现 SimpleApplicationEventMulticaster这个事件发布对象持有所有listenter对象及MyEvent对象 , 事件发布过程其实就是遍历拿到每个li

    2024年02月12日
    浏览(42)
  • Java 后端实现鼠标滚动,点击事件

    参考:Java-随机滑动鼠标和点击_胡安民的博客-CSDN博客_java移动鼠标点击 import java.awt.*; public class MouseTest {     private Dimension dim; //存储屏幕尺寸     private Robot robot;//自动化对象     public MouseTest() {         dim = Toolkit.getDefaultToolkit().getScreenSize();         System.out.println(\\\"屏幕大

    2024年02月14日
    浏览(51)
  • Spring Boot 整合 Shiro(后端)

    1 Shiro 什么是 Shiro 官网: http://shiro.apache.org/ 是一款主流的 Java 安全框架,不依赖任何容器,可以运行在 Java SE 和 Java EE 项目中,它的主要作用是对访问系统的用户进行身份认证、 授权、会话管理、加密等操作。 Shiro 就是用来解决安全管理的系统化框架。 2 Shiro 核心组件 用

    2024年02月09日
    浏览(49)
  • 【Spring | 事件监听详解】

    上篇 Spring 事件监听概述 对 Spring 事件监听的机制有了个基本的了解。 本篇来详细的解读下Spring 的 事件监听机制 。    ApplicationEvent 最重要的子类是 ApplicationContextEvent 抽象类, ApplicationContextEvent 是spring容器Context生命周期事件的基类。 ApplicationContextEvent 的有四个子类,如

    2024年02月12日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包