1. 程式人生 > >spring事件機制-onApplicationEvent執行兩次

spring事件機制-onApplicationEvent執行兩次

一、case復現

事件定義

Java程式碼  收藏程式碼
  1. public class MyEvent extends ApplicationEvent {  
  2.     public MyEvent(Object object) {  
  3.         super(object);  
  4.     }  
  5. }  

監聽定義

Java程式碼  收藏程式碼
  1. @Component  
  2. public class MyListener implements ApplicationListener<MyEvent> {  
  3.     @Override  
  4.     public void onApplicationEvent(MyEvent event) {  
  5.         System.out.println("myEvent occured msg : " + event.getSource());  
  6.     }  
  7. }  

事件通知

Java程式碼  收藏程式碼
  1. @ResponseBody  
  2. @RequestMapping(value = "/publish")  
  3. public String publish(String key) {  
  4.      BeanFactory.pushEvent(new MyEvent("publish"));  
  5.      return "success";  
  6. }  
Java程式碼  收藏程式碼
  1. @Component  
  2. public class BeanFactory implements
     ApplicationContextAware {  
  3.     private static ApplicationContext applicationContext;  
  4.     public static <T> T getBean(String beanName, Class<T> clazz) {  
  5.         return (T) applicationContext.getBean(beanName);  
  6.     }  
  7.     /** 
  8.      * 通知事件 
  9.      * 
  10.      * @param applicationEvent 
  11.      */  
  12.     public
     static void pushEvent(ApplicationEvent applicationEvent) {  
  13.         //獲取父容器傳送事件  
  14.         //ContextLoader.getCurrentWebApplicationContext().publishEvent(applicationEvent);  
  15.         applicationContext.publishEvent(applicationEvent);  
  16.     }  
  17.     @Override  
  18.     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
  19.         this.applicationContext = applicationContext;  
  20.     }  
  21.     public static ApplicationContext getApplicationContext() {  
  22.         return applicationContext;  
  23.     }  
  24. }  

 測試結果:

Java程式碼  收藏程式碼
  1. myEvent occured msg : publish  
  2. myEvent occured msg : publish  

三、原因

在web專案中如果同時集成了spring和springMVC的話,上下文中會存在兩個容器,即spring的applicationContext.xml的父容器和springMVC的applicationContext-mvc.xml的子容器。

在通過applicationContext傳送通知的時候,事件會被兩個容器釋出,造成上述情況。

四、解決方案

知道了原因,解決方案就比較簡單了,看了網上大多數的方案都是

Java程式碼  收藏程式碼
  1. @Override  
  2. public void onApplicationEvent(ContextRefreshedEvent event) {  
  3.     if(event.getApplicationContext().getParent() == null){  
  4.          //需要執行的邏輯程式碼,當spring容器初始化完成後就會執行該方法。  
  5.     }  
  6. }  

 但這種方案先定了事件的型別,自定義的事件是行不通的,所以解決方案的思路是用父容器去傳送通知

Java程式碼  收藏程式碼
  1. /** 
  2.  * 通知事件 
  3.  * 
  4.  * @param applicationEvent 
  5.  */  
  6. public static void pushEvent(ApplicationEvent applicationEvent) {  
  7.     //獲取父容器傳送事件  
  8.     ContextLoader.getCurrentWebApplicationContext().publishEvent(applicationEvent);  
  9. }  

 測試結果:

Java程式碼  收藏程式碼
  1. myEvent occured msg : publish  

 至此,解決了這個case的問題,多大家有更好更多的方案,希望留言一起學習

相關推薦

spring事件機制-onApplicationEvent執行

一、case復現事件定義Java程式碼  public class MyEvent extends ApplicationEvent {      public MyEvent(Object object) {          super(object);      }  

Spring事件處理——onApplicationEvent執行.md

我們知道Spring有兩大類事件,一類是Application事件,超類是SpringApplicationEvent,這類事件是在Spring程式啟動時,過程中分為幾個階段,每進行一個階段,發出一個事件,依次對應ApplicationStartingEvent到ApplicationR

SpirngMVC系統啟動系統配置初始化執行順序以及防止onApplicationEvent執行

Spirng系統啟動容器執行順序 這裡面加入了springMVC,因此基本的啟動執行後用到的過載方法都列出來了,下面的logger.info中給出了前後執行的順序次序,可以根據自己的需求進行修改,但是這個時候,會存在一個問題onApplicationEvent

spring quartz執行問題

p s 解決 項目 信息 nbsp 觸發 san orm app 解決quartz定時任務被觸發兩次的問題: 其中<Host/>告訴tomcat,在啟動的時候加載webapps下的所有項目工程文件,<Context/>又讓tomcat再加載了一遍(一

spring定時任務執行的原因與解決方法

ref net 任務 article 服務 每次 bsp tail 本地 spring定時任務,本地執行一次,放到服務器上後,每次執行時會執行兩次,原因及解決辦法。 http://blog.csdn.net/yaobengen/article/details/70312

分析解決 spring quartz 中出現的執行問題

color src bat class 故事 重復 功能 fig 再次 1. 問題描述 在開發詢盤功能時,遇到一個需求,就是後臺定時任務執行用電施工業務的工單下發。 使用的技術是 spring quartz,因為其他應用有先例,配置quartz 完成後,先寫了一個 hell

記:一 spring cloud @PostConstruct 執行的分析

1、前言 最近遇到一個情況,@PostConstruct 方法會被執行兩次,感覺有點奇怪,跟蹤程式碼簡單分析了下,場景有點特殊,這裡記錄下。 @PostConstruct屬於JSR250規範,在bean建立完成並且屬性賦值完成之後會執行該初始化方法。 內部通

關於JComboBox觸發事件總是執行

1、今天用到JcomBox,在JComboBox的監聽事件時總是執行兩次。 程式碼如下: comboBox.addItemListener(new ItemListener() { @Override public void itemState

spring 定時任務執行解決辦法

今天在做一個專案的時候用到了Spring的定時計劃任務。這是Spring的特色功能,可以根據設定在特定的時間或間隔時間做特定的事。下面給出一個例子:package net.csdn.blog.chaijunkukn; import java.text.SimpleDateF

spring定時器,定時器一執行的問題

今天在做一個專案的時候用到了Spring的定時計劃任務。這是Spring的特色功能,可以根據設定在特定的時間或間隔時間做特定的事。 下面給出一個例子: package net.csdn.blog.chaijunkukn;   import

Spring定時器在同一時間重複執行

轉自: http://blog.sina.com.cn/s/blog_4c03369c0101tbtj.html 最近用Spring的quartz定時器的時候,發現到時間後,任務總是重複執行兩次,在tomcat或jboss下都如此。打印出他們的hashcode,發現是

關於Spring中用quartz定時器在定時到達時同時執行的問題

我在使用spring的quartz配置定時任務時,發現每次定時時間到達後,指定的定時方法同時執行兩次,而且此方法還是使用的synchronized關鍵字,每次定時一到,會發現此方法內的System.out輸出資訊輸出兩次,說明方法在這時執行了兩次,解決方法沒有找到更好的,不過

spring 定時器執行

spring錯誤筆記 spring定時器執行兩次因為匯入了兩次 關於配置檔案如下 <bean id="timeTaskService" class="xx.xxx.xxx.xxx.service.impl.na.TimeTaskService"/><ta

spring 定時任務執行

最近用spring的quartz定時器的時候,發現到時間後,任務總是重複執行兩次,在tomcat或jboss下都如此。 打印出他們的hashcode,發現是不一樣的,也就是說,在web容器啟動的時候

解決Spring task 重複執行

spring task的建立方法http://blog.csdn.net/qq_22585453/article/details/53635901 重複執行的的解決方案:Tomcat伺服器的問題

Spring @Scheduled 執行 問題總結

參考:http://bbs.csdn.net/topics/391054322 使用 Spring @Scheduled 註解實現定時任務:  1:servlet.xml中添加了 task名稱空間 和  XML/HTML code ? 1 <tas

用jquery 繫結一個按鈕click事件後,第一點選後,一切正常,第二點選,竟然執行,以後越來越多

用jquery  繫結一個按鈕click事件後,第一次點選後,一切正常,第二次點選,竟然執行兩次,以後越來越多。 後來檢視文件發現  jquery click  不是 替換原有的function  而是接著新增,所以才會執行次數越來越多。 這有就可以在新增之前要先解除cli

spring mvc請求一,controll執行(ajax,谷歌瀏覽器)

一大早碰上的在谷歌瀏覽器弄的登入網頁在form表單下的button中用的onclikc方法呼叫的function 點選登入,傳送一個ajax請求,結果後臺controll都是馬上執行兩次,一次引數有值,一次接收不到任何引數解決: 把form表單刪除就行了,還不清楚原因

用jquery 繫結一個按鈕click事件後,第一點選後,一切正常,第二點選,竟然執行,以後越來越多

用jquery  繫結一個按鈕click事件後,第一次點選後,一切正常,第二次點選,竟然執行兩次,以後越來越多, 後來檢視文件發現  jquery click  不是 替換原有的function  而是接著新增,所以才

input內容改變後,ie11中change事件執行的解決辦法

頁面檔案上傳,程式碼如下: <form id="subId" action="doc/uploadTranslate"enctype="multipart/form-data"method="p