`
后来我们都老了
  • 浏览: 34637 次
  • 性别: 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
分享到:
评论

相关推荐

    使用Spring事件机制实现异步的方法

    使用Spring事件机制实现异步的方法 Spring框架提供了一种事件机制,允许开发者将代码解耦合,实现松散耦合的设计理念。这里将详细介绍如何使用Spring事件机制实现异步的方法。 事件机制的实现主要包括三个部分:...

    spring事件机制

    这个机制允许一个组件(通常是一个服务)触发一个事件,然后其他感兴趣的组件(称为监听器)可以响应这个事件并执行相应的操作。 首先,我们来理解一下事件(Event)和事件监听器(EventListener)的概念。在Spring...

    event.rar-Spring事件监听机制

    在Spring框架中,事件监听机制是一种非常重要的组件间通信方式,它允许应用程序的不同部分通过发布和订阅事件来进行异步通信。这种模式使得组件之间松耦合,提高了代码的可维护性和可扩展性。下面我们将详细探讨...

    深入探索Spring事件监听机制:技术与应用

    Spring事件监听机制是Spring框架中的一个重要特性,它基于经典的观察者模式,允许应用程序组件之间进行松耦合的通信。在Spring中,事件监听机制由三部分组成:事件(ApplicationEvent)、事件监听器(Application...

    JAVA-spring学习资源之spring事件

    在这个"JAVA-spring学习资源之spring事件"中,我们将深入探讨这两个方面,并通过具体的示例来理解它们的工作原理。 首先,让我们来理解什么是Spring事件。Spring事件是基于观察者模式实现的,它提供了一种在应用...

    详解Spring事件驱动模型

    一、Spring事件机制的工作流程 1. 定义事件:创建自定义的事件类,继承自`ApplicationEvent`。例如,可以创建一个`CustomEvent`表示特定业务操作完成的事件。 2. 注册监听器:编写`ApplicationListener`接口的实现...

    phase3-spring-event-handling-03-24-2021:phase3-spring-event-handling-03-24-2021

    标题和描述中提到的"phase3-spring-event-handling-03-24-2021"似乎是一个关于Spring框架事件处理的学习项目,日期为2021年3月24日。从标签"Java"我们可以推断,这个项目是使用Java语言,并且与Spring框架的事件处理...

    spring 事件处理

    在Spring框架中,事件处理是一种重要的通信机制,它允许组件之间进行解耦的通信。Spring事件处理基于发布/订阅模式,其中事件是消息的载体,而事件监听器则是对这些消息感兴趣的订阅者。在这个场景中,我们将探讨...

    spring事件的例子

    在Spring框架中,事件处理是一种重要的组件间通信方式。它允许一个对象在完成特定操作后,通知其他对象这一事实,而无需这些对象之间有直接的依赖关系。这种机制基于Java的观察者模式(Observer Pattern),使得松...

    Java版本ngrok集成spring-boot随应用启动快速映射内网地址

    这种隧道机制使得开发者无需公开服务器的真实IP,就能安全地访问内网资源。Java版的ngrok实现了这一功能,并提供了与Spring Boot的集成方案。 Spring Boot是Java领域非常流行的轻量级框架,它简化了创建独立、生产...

    详解spring boot容器加载完后执行特定操作

    在 Spring Boot 应用程序中,容器加载完成后,框架会触发 ContextRefreshedEvent 事件,该事件表明容器已经加载完成,可以执行特定操作了。我们可以创建一个实现 ApplicationListener 接口的类,用于监听 ...

    Spring事件管理

    在Spring框架中,事件管理是一种强大的机制,它允许在应用程序组件之间传递消息,而无需这些组件之间有直接的依赖关系。这种松耦合的方式提高了代码的可维护性和可测试性。接下来,我们将深入探讨Spring事件管理的...

    spring注解Quartz定时执行功能

    下面我们将深入探讨如何利用Spring注解实现Quartz定时执行功能。 首先,我们需要引入Quartz和Spring的相关依赖。在Maven的pom.xml文件中添加以下依赖: ```xml &lt;groupId&gt;org.quartz-scheduler &lt;artifactId&gt;...

    spring 事件监听 3种方式

    Spring事件监听机制使得我们可以松散地耦合应用程序组件,提高代码的可维护性和扩展性。根据项目需求和场景,可以选择合适的方式实现事件监听。基于接口的监听器适合于早期版本的Spring,基于类的监听器提供了一种更...

    spring-events-test:开发项目以展示基于 Spring 事件的发布者和订阅者

    在Spring框架中,事件驱动模型是一种松耦合的通信机制,允许不同的组件之间进行异步消息传递。"spring-events-test"项目就是为了解释和演示如何在Spring应用中使用事件系统。下面我们将深入探讨这个话题。 ### 1. ...

    Spring的配置以及事件注入

    本篇文章将深入探讨Spring的配置和事件注入机制,帮助开发者更好地理解和利用这些特性。 首先,让我们关注Spring的配置。Spring的配置主要有两种方式:XML配置和Java配置。在早期的Spring版本中,XML配置是最常用的...

    spring 时间机制

    Spring的ApplicationContext事件机制是框架提供的一种解耦组件之间交互的方式,允许组件在不直接依赖其他组件的情况下进行通信。这一机制类似于传统的Windows编程中对事件的处理,但更加面向服务和面向对象。 在...

    第十七章 Spring 事件(Events)1

    在Spring框架中,事件处理是一种重要的通信机制,它允许组件之间进行解耦的通信。本章将深入探讨Spring事件(Events)的相关知识点。 首先,Java事件/监听器编程模型是基于观察者模式的,该模式定义了对象之间的一...

    spring中监听事件

    当调用此方法时,Spring会查找所有注册的`ApplicationListener`,并将事件对象传递给它们的`onApplicationEvent`方法。`ApplicationListener`是接口,任何实现了这个接口的类都可以作为事件监听器,监听并处理特定...

    J2EE企业级项目开发-1期 08 Spring中事件处理的小技巧.doc

    在Spring框架中,事件处理是一种强大的机制,它允许在应用程序的不同组件之间进行解耦通信。在J2EE企业级项目开发中,理解并熟练运用Spring的事件处理小技巧至关重要。以下将详细介绍Spring事件处理的核心概念、工作...

Global site tag (gtag.js) - Google Analytics