`
后来我们都老了
  • 浏览: 33837 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring事件机制-onApplicationEvent执行两次

阅读更多

一、case复现

事件定义

 

public class MyEvent extends ApplicationEvent {

    public MyEvent(Object object) {
        super(object);
    }
}

 

 

监听定义

 

@Component
public class MyListener implements ApplicationListener<MyEvent> {

    @Override
    public void onApplicationEvent(MyEvent event) {
        System.out.println("myEvent occured msg : " + event.getSource());
    }
}

 

 

事件通知

 

@ResponseBody
@RequestMapping(value = "/publish")
public String publish(String key) {
     BeanFactory.pushEvent(new MyEvent("publish"));
     return "success";
}

 

 

 

@Component
public class BeanFactory implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    public static <T> T getBean(String beanName, Class<T> clazz) {
        return (T) applicationContext.getBean(beanName);
    }

    /**
     * 通知事件
     *
     * @param applicationEvent
     */
    public static void pushEvent(ApplicationEvent applicationEvent) {
        //获取父容器发送事件
        //ContextLoader.getCurrentWebApplicationContext().publishEvent(applicationEvent);
        applicationContext.publishEvent(applicationEvent);
    }

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

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}

 测试结果:

 

myEvent occured msg : publish
myEvent occured msg : publish

 

 

三、原因

在web项目中如果同时集成了spring和springMVC的话,上下文中会存在两个容器,即spring的applicationContext.xml的父容器和springMVC的applicationContext-mvc.xml的子容器。

在通过applicationContext发送通知的时候,事件会被两个容器发布,造成上述情况。

四、解决方案

知道了原因,解决方案就比较简单了,看了网上大多数的方案都是

   @Override
   public void onApplicationEvent(ContextRefreshedEvent event) {
       if(event.getApplicationContext().getParent() == null){
            //需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。
       }
   }

 但这种方案先定了事件的类型,自定义的事件是行不通的,所以解决方案的思路是用父容器去发送通知

    /**
     * 通知事件
     *
     * @param applicationEvent
     */
    public static void pushEvent(ApplicationEvent applicationEvent) {
        //获取父容器发送事件
        ContextLoader.getCurrentWebApplicationContext().publishEvent(applicationEvent);
    }

 测试结果:

myEvent occured msg : publish

 至此,解决了这个case的问题,多大家有更好更多的方案,希望留言一起学习

 

 

 

 

 

0
0
分享到:
评论

相关推荐

    SpringBoot事件发布及订阅详解含代码示例(值得珍藏)

    当某个特定的事件发生时,ApplicationEvent 对象会被创建并发布到 ApplicationContext 中,所有注册监听该事件的监听器就会收到通知并执行相应的操作。 ApplicationEvent 是一个泛型类,可以用来传递任何类型的数据...

    【车牌识别】 GUI BP神经网络车牌识别(带语音播报)【含Matlab源码 668期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    【作业视频】六年级第1讲--计算专项训练(2022-10-28 22-51-53).mp4

    【作业视频】六年级第1讲--计算专项训练(2022-10-28 22-51-53).mp4

    3文件需求申请单.xls

    3文件需求申请单.xls

    【脑肿瘤检测】 GUI SOM脑肿瘤检测【含Matlab源码 2322期】.zip

    【脑肿瘤检测】 GUI SOM脑肿瘤检测【含Matlab源码 2322期】

    GOGO语言基础教程、实战案例和实战项目讲解

    GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解

    全国计算机等级考试二级笔试样卷C语言程序设计

    全国计算机等级考试二级笔试样卷C语言程序设计主要考察考生对C语言编程的基础知识、语法和编程能力的掌握程度。考试内容主要包括C语言程序的结构、数据类型及其运算等基础知识,以及循环、条件语句、函数等编程能力。

    Excel模板个人简历文艺清新单页01.docx

    Excel模板个人简历文艺清新单页01.docx

    【图像边缘检测】自适应阈值的八方向和四方向sobel图像边缘检测【含Matlab源码 2058期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    HC070-3.5标定版描述文件及标定版ps文件

    HC070-3.5标定版描述文件及标定版ps文件

    【目标跟踪】 GUI帧差法结合卡尔曼滤波行人姿态识别【含Matlab源码 1127期】.zip

    【目标跟踪】 GUI帧差法结合卡尔曼滤波行人姿态识别【含Matlab源码 1127期】

    ISO文件电子文档发文删文记录表.xls

    ISO文件电子文档发文删文记录表.xls

    【红绿灯识别】机器视觉红绿灯识别【含Matlab源码 4044期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    【图像去噪】稀疏表示KSVD彩色图像去噪(含PSNR)【含Matlab源码 4261期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    node-v0.10.48-sunos-x86.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v0.10.48-linux-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    PREEvision关于ECU软件与诊断设计的一致性功能

    PREEvision关于ECU软件与诊断设计的一致性功能

    6c148dfb275925c73ba1861abbac5235.amr

    6c148dfb275925c73ba1861abbac5235.amr

    【图像隐写】 Jsteg算法JPEG图像信息隐藏(可设置DCT系数 嵌入率)【含Matlab源码 4235期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    【跌倒检测】 GUI人体跌倒检测系统【含Matlab源码 2428期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

Global site tag (gtag.js) - Google Analytics