我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Spring/SpringBoot 事件监听机制是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Spring/SpringBoot 事件监听机制是什么

本篇文章给大家分享的是有关Spring/SpringBoot 事件监听机制是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

事件监听机制可以理解为是一种观察者模式,有数据发布者(事件源)和数据接受者(监听器);

在Java中,事件对象都是继承java.util.EventObject对象,事件监听器都是java.util.EventListener实例;

EventObject对象不提供默认构造器,需要外部传递source参数,即用于记录并跟踪事件的来源;

Spring事件

Spring事件对象为ApplicationEvent,继承EventObject,源码如下:

public abstract class ApplicationEvent extends EventObject {           public ApplicationEvent(Object source) {         super(source);         this.timestamp = System.currentTimeMillis();     }  }

Spring事件监听器为ApplicationListener,继承EventListener, 源码如下:

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {     void onApplicationEvent(E var1); }

实现Spring事件监听有两种方式:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 面向接口编程,实现ApplicationListener接口;

  3. 基于注解驱动,@EventListener(Spring自定义的注解);

实例:

面向接口编程,实现ApplicationListener接口:

自定义事件对象:

public class MyApplicationEvent extends ApplicationEvent {     public MyApplicationEvent(Object source) {         super(source);     } }

自定义事件监听器:

public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {     @Override     public void onApplicationEvent(MyApplicationEvent event) {         System.out.println("收到事件:" + event);     } }

启动服务并发布事件:

public class ApplicationEventBootstrap {      public static void main(String[] args) {         AnnotationConfigApplicationContext context =                 new AnnotationConfigApplicationContext();         // 注册自定义事件监听器         context.addApplicationListener(new MyApplicationListener());         // 启动上下文         context.refresh();         // 发布事件,事件源为Context         context.publishEvent(new MyApplicationEvent(context));         // 结束         context.close();     } }

运行结果:

收到事件:com.xx.MyApplicationEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@cb0ed20, started on Sat May 16 16:32:04 CST 2020]

使用注解 @EventListener实现Spring事件监听:

@Component public class MyApplicationListener2 {      @EventListener(MyApplicationEvent.class)     public void onEvent(MyApplicationEvent event) {         System.out.println("收到事件:" + event);     } }

启动并发布事件:

public class ApplicationEventBootstrap {      public static void main(String[] args) {         AnnotationConfigApplicationContext context =                 new AnnotationConfigApplicationContext();         // 注册自定义事件监听器         context.register(MyApplicationListener2.class);         // 启动上下文         context.refresh();         // 发布事件,事件源为Context         context.publishEvent(new MyApplicationEvent(context));         // 结束         context.close();     } }

运行结果:

收到事件:com.xx.MyApplicationEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@cb0ed20, started on Sat May 16 16:32:04 CST 2020]

通过实例可以看出,上面两种方式都可正常发布和接收事件。

实现原理

通过上面实例可以看出,context 可以发布事件,那底层是怎么发布的,让我们继续看源码:

public abstract class AbstractApplicationContext extends DefaultResourceLoader         implements ConfigurableApplicationContext {       protected void publishEvent(Object event, @Nullable ResolvableType eventType) {         ...         getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);         ...       } }

通过源码我们可以看出,事件应该是通过

ApplicationEventMulticaster发布的,我们继续看:

public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster

Spring 中事件发布都是通过

SimpleApplicationEventMulticaster来实现的

public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {         ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));         for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {             Executor executor = getTaskExecutor();             if (executor != null) {         // 异步                 executor.execute(() -> invokeListener(listener, event));             }             else {                 invokeListener(listener, event);             }         }     }

可以看出,如果设置了Executor则异步发送,否则同步;而且可以看出通过 resolveDefaultEventType(event)  对发布的事件类型进行了校验,这就是为什么我们可以直接使用泛型来指定我们想接收的事件对象, 比如上面的 ApplicationListener。

private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {         try {             listener.onApplicationEvent(event);

最后就使用对应的ApplicationListener进行接收和处理就行了,那么ApplicationListener是什么时候注册的呢?

如何添加ApplicationListener?

  1. 直接添加,使用content.addApplicationListener(上面实例中有使用);

  2. 将自定义的ApplicationListener注册为一个Bean,Spring再初始化Bean之后会添加,具体代码在ApplicationListenerDetector#postProcessAfterInitialization,判断一个Bean如果是ApplicationListener,则也是使用context.addApplicationListener添加;

  3. 使用注解@EventListener,在初始化Bean之后,会在EventListenerMethodProcessor中进行处理和添加;

第三种实现的源码如下(

EventListenerMethodProcessor中):

private void processBean(final String beanName, final Class<?> targetType) {   ....   // 获取public 且有@EventListener的方法    AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));   ...    ApplicationListener<?> applicationListener = factory.createApplicationListener(beanName, targetType, methodToUse);                    // 添加监听器   context.addApplicationListener(applicationListener);  }

Spring内建事件

  • ContextRefreshedEvent: Spring应用上下文就绪事件;

  • ContextStartedEvent: Spring应用上下文启动事件;

  • ContextStopedEvent: Spring应用上下文停止事件;

  • ContextClosedEvent: Spring应用上下文关闭事件;

Spring Boot事件

Spring Boot事件是在Spring事件基础上进行的封装

public abstract class SpringApplicationEvent extends ApplicationEvent

事件对象改为SpringApplicationEvent,事件源为SpringApplication(Spring事件源为Context);

底层发布事件还是使用

SimpleApplicationEventMulticaster 对象,不过有点需要说明的是,Spring Boot  1.4开始,SpringApplication和ApplicationContext使用的都是

SimpleApplicationEventMulticaster实例,但是两者属于不同的对象(1.0 ~ 1.3版本是同一个对象);

事件回顾:

public class EventBootstrap {      public static void main(String[] args) {         new SpringApplicationBuilder(Object.class)                 .listeners(event -> {                     System.out.println("事件对象:"                     + event.getClass().getSimpleName()                     + " ,事件源:" + event.getSource().getClass().getSimpleName());                 })                 .web(WebApplicationType.NONE)                 .run(args)                 .close();     } }

运行结果:

事件对象:ApplicationContextInitializedEvent ,事件源:SpringApplication 事件对象:ApplicationPreparedEvent ,事件源:SpringApplication 事件对象:ContextRefreshedEvent ,事件源:AnnotationConfigApplicationContext 事件对象:ApplicationStartedEvent ,事件源:SpringApplication 事件对象:ApplicationReadyEvent ,事件源:SpringApplication 事件对象:ContextClosedEvent ,事件源:AnnotationConfigApplicationContext

从结果可以看出,事件对象类型和事件源,以及事件发布顺序。

以上就是Spring/SpringBoot 事件监听机制是什么,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Spring/SpringBoot 事件监听机制是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Spring/SpringBoot 事件监听机制是什么

本篇文章给大家分享的是有关Spring/SpringBoot 事件监听机制是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。事件监听机制可以理解为是一种观察者模式,有数据发布
2023-06-17

JavaGUI事件监听机制是什么

今天小编给大家分享一下JavaGUI事件监听机制是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.一个事件模型中有上对
2023-07-05

Java中的事件监听机制是什么

这篇文章给大家介绍Java中的事件监听机制是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。鼠标事件监听机制的三个方面:1.事件源对象:事件源对象就是能够产生动作的对象。在Java语言中所有的容器组件和元素组件都是事
2023-05-31

Spring的事件发布与监听方式是什么

本篇内容介绍了“Spring的事件发布与监听方式是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!事件主要代码在org.springfra
2023-07-05

Spring事件发布与监听机制的用法示例

小编给大家分享一下Spring事件发布与监听机制的用法示例,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、ApplicationContext 事件机制Appl
2023-06-20

使用Spring怎么监听事件

使用Spring怎么监听事件?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、观察者模式先来看下观察者模式,举个例子警察和军人是观察者,犯罪嫌疑人是被观察者代码实现:定义被观察
2023-06-15

springboot事件监听器怎么使用

本篇内容介绍了“springboot事件监听器怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!引导案例下面看一个简单的案例,@Conf
2023-07-02

layui table事件监听与处理机制详解(解析layui table的事件监听和处理机制)

layuitable事件监听机制提供了丰富的事件类型和处理机制,允许开发者响应表格操作和数据交互。事件监听器通过HTML属性或JavaScriptAPI注册,触发事件时会调用对应的处理函数并填充相关数据。开发者可根据需要执行自定义逻辑,并返回布尔值控制后续操作。layuitable的事件监听功能助力开发者扩展表格功能,增强交互性,满足多样化业务需求。
layui table事件监听与处理机制详解(解析layui table的事件监听和处理机制)
2024-04-02

JavaGUI事件监听机制超详细讲解

Java事件监听器是由事件类和监听接口组成,自定义一个事件前,必须提供一个事件的监听接口以及一个事件类。JAVA中监听接口是继承java.util.EventListener的类,事件类继承java.util.EventObject的类
2023-03-03

Spring事件发布与监听怎么实现

这篇文章主要讲解了“Spring事件发布与监听怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Spring事件发布与监听怎么实现”吧!  一、事件监听相关概念介绍  1、流程分析  事
2023-06-02

JS添加事件监听的方法是什么

这篇文章主要介绍“JS添加事件监听的方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JS添加事件监听的方法是什么”文章能帮助大家解决问题。1.我们一般在的事件添加时是这样做的:elm.onc
2023-06-26

jQuery3种常见事件监听方式是什么

这篇文章主要为大家展示了“jQuery3种常见事件监听方式是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“jQuery3种常见事件监听方式是什么”这篇文章吧。1.HTML标签内联事件实例1:
2023-06-29

Flutter事件监听与EventBus事件应用的方法是什么

这篇文章主要介绍“Flutter事件监听与EventBus事件应用的方法是什么”,在日常操作中,相信很多人在Flutter事件监听与EventBus事件应用的方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家
2023-07-06

如何实现Flex键盘事件的监听机制

这篇文章给大家分享的是有关如何实现Flex键盘事件的监听机制的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Flex键盘事件的监听Flex的事件监听机制很完善,下面主要简单的讲一下Flex键盘事件的监听。首先,要理
2023-06-17

Java键盘事件处理及监听机制解析

文章目录 概念KeyEventKeyListener代码演示总结 概念 Java事件处理采用了委派事件模型。在这个模型中,当事件发生时,产生事件的对象将事件信息传递给事件的监听者进行处理。在Java中,事件源是产生事件的对象,
2023-08-20

什么是Flex事件机制

这篇文章主要为大家展示了“什么是Flex事件机制”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“什么是Flex事件机制”这篇文章吧。Flex事件机制介绍1.什么是Flex事件机制Flex事件可以看
2023-06-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录