關於JAVA中事件分發和監聽機制實現的代碼實例-絕對原創實用

轉載:http://blog.csdn.net/5iasp/article/details/37054171

謝謝博主

=======================================================================================================

文章標題:關於Java中事件分發和監聽機制實現的代碼實例

文章地址: http://blog.csdn.net/5iasp/article/details/37054171

作者: javaboy2012
Email:[email protected]
qq:    1046011462

 

 

一、場景假設

假設有博客系統中需要實現如下功能:

系統中用戶發佈文章,修改文章,刪除文章時,需要一些相關的操作需要執行。


發佈文章後,給好友發送郵件通知,給用戶加積分,對文章做全文索引。
修改文章後,給好友發送郵件修改通知,給用戶加積分,對文章重新做全文索引。
刪除文章後,給好友發送郵件修改通知,給用戶減少積分,對文章重新做全文索引。

 

二、相關的概念解析

   分析如上場景,可以採用事件分發和監聽機制來實現。

 
  事件分發和監聽有如下幾個概念:


 事件源:觸發事件的對象 如上場景中我們把實體對象作爲事件源,發佈的文章就是事件源

 事件: 對事件源的操作產生事件,例如 發表文章 修改文章,刪除文章這些操作就會觸發相關的 文章被髮表事件,文章被刪除事件,文章被修改事件

 事件監聽器:對事件源各種事件觸發執行行爲的抽象,包括接口和若干實現類。

    比如: 接口需要定義事件源相關事件觸發時需要實現的操作接口。

 事件分發器:事件分發器主要處理事件的分發和事件監聽器的管理,註冊和刪除事件監聽器等。   

 

三、 代碼示例

 

項目結構:

 


根據上述概念相關代碼如下:


  包括如下代碼

  1. 博客文章類  屬於事件源

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.yanek.event;  
  2. /** 
  3.  * 博客文章 
  4.  * @author Administrator 
  5.  * 
  6.  */  
  7. public class Entry {  
  8.       
  9.       
  10.     public long getId() {  
  11.         return id;  
  12.     }  
  13.     public void setId(long id) {  
  14.         this.id = id;  
  15.     }  
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.     public void setName(String name) {  
  20.         this.name = name;  
  21.     }  
  22.     private long id; // 編號  
  23.     private String name; //標題  
  24.       
  25. }  


 

2. 博客文章事件類 屬於事件對象

其中定義了事件的類型和事件源,事件參數

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.yanek.event;  
  2.   
  3. import java.util.Collections;  
  4. import java.util.Date;  
  5. import java.util.Map;  
  6. /** 
  7.  * 博客文章事件 
  8.  * @author Administrator 
  9.  * 
  10.  */  
  11. public class EntryEvent  
  12.   
  13. {  
  14.   
  15.     public static final int ENTRY_ADDED = 100//事件類型:博客文章被創建  
  16.     public static final int ENTRY_DELETED = 101;//事件類型:博客文章被刪除  
  17.     public static final int ENTRY_MODIFIED = 102;//事件類型:博客文章被修改  
  18.   
  19.     private int eventType; //事件類型  
  20.     private Entry entry; //博客文章對象  
  21.     private Date date; //事件觸發日期  
  22.     private Map params; //事件輔助參數  
  23.   
  24.     public EntryEvent(int eventType, Entry entry, Map params) {  
  25.         this.eventType = eventType;  
  26.         this.entry = entry;  
  27.         this.params = params != null ? Collections.unmodifiableMap(params)  
  28.                 : null;  
  29.         date = new Date();  
  30.     }  
  31.   
  32.     public int getEventType() {  
  33.         return eventType;  
  34.     }  
  35.   
  36.     public Entry getEntry() {  
  37.         return entry;  
  38.     }  
  39.   
  40.     public Map getParams() {  
  41.         return params;  
  42.     }  
  43.   
  44.     public Date getDate() {  
  45.         return date;  
  46.     }  
  47. }  


 

3. 事件監聽器接口和實現類:

定義各種事件發生時需要處理的接口方法

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.yanek.event;  
  2. /** 
  3.  * 博客文章監聽器接口 
  4.  * @author Administrator 
  5.  * 
  6.  */  
  7. public interface EntryListener  
  8. {  
  9.     /** 
  10.      * 博客文章被創建 
  11.      * @param entryevent 
  12.      */  
  13.     public abstract void entryAdded(EntryEvent entryevent);   
  14.       
  15.     /** 
  16.      * 博客文章被刪除 
  17.      * @param entryevent 
  18.      */  
  19.   
  20.     public abstract void entryDeleted(EntryEvent entryevent);  
  21.       
  22.       
  23.     /** 
  24.      * 博客文章被修改 
  25.      * @param entryevent 
  26.      */  
  27.     public abstract void entryModified(EntryEvent entryevent);  
  28.   
  29. }  


 

事件監聽器接口的實現類:


   實現場景中的三類操作,監聽器接口實現包括如下三個類實現

   
  IndexManager 索引管理器類 
  ScoreManager 積分管理器類
  EmailManager 郵件管理器類

  三個類都實現監聽器接口EntryListener。具體代碼如下:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1.  package com.yanek.event;  
  2.   
  3.   
  4.   
  5. /** 
  6.  * 郵件管理器 
  7.  * @author Administrator 
  8.  * 
  9.  */  
  10. public class EmailManager implements EntryListener{  
  11.   
  12.     @Override  
  13.     public void entryAdded(EntryEvent entryevent) {  
  14.   
  15.         System.out.println("EmailManager 處理 博客文章被創建事件。");  
  16.           
  17.     }  
  18.       
  19.     @Override  
  20.     public void entryDeleted(EntryEvent entryevent) {  
  21.   
  22.         System.out.println("EmailManager 處理 博客文章被刪除事件。");  
  23.     }  
  24.     @Override  
  25.     public void entryModified(EntryEvent entryevent) {  
  26.       
  27.         System.out.println("EmailManager 處理 博客文章被修改事件。");  
  28.           
  29.     }  
  30.   
  31.   
  32. }  
  33.   
  34.   
  35.   
  36. package com.yanek.event;  
  37. /** 
  38.  * 索引管理器 
  39.  * @author Administrator 
  40.  * 
  41.  */  
  42. public class IndexManager implements EntryListener {  
  43.   
  44.     @Override  
  45.     public void entryAdded(EntryEvent entryevent) {  
  46.   
  47.   
  48.         System.out.println("IndexManager 處理 博客文章被創建事件。");  
  49.           
  50.     }  
  51.   
  52.     @Override  
  53.     public void entryDeleted(EntryEvent entryevent) {  
  54.         // TODO Auto-generated method stub  
  55.         System.out.println("IndexManager 處理 博客文章被刪除事件。");  
  56.           
  57.     }  
  58.   
  59.     @Override  
  60.     public void entryModified(EntryEvent entryevent) {  
  61.         // TODO Auto-generated method stub  
  62.         System.out.println("IndexManager 處理 博客文章被修改事件。");  
  63.     }  
  64.   
  65. }  
  66.   
  67.   
  68.   
  69. package com.yanek.event;  
  70. /** 
  71.  * 積分管理器 
  72.  * @author Administrator 
  73.  * 
  74.  */  
  75. public class ScoreManager implements EntryListener {  
  76.   
  77.     @Override  
  78.     public void entryAdded(EntryEvent entryevent) {  
  79.         System.out.println("ScoreManager 處理 博客文章被創建事件。");  
  80.           
  81.     }  
  82.   
  83.     @Override  
  84.     public void entryDeleted(EntryEvent entryevent) {  
  85.         // TODO Auto-generated method stub  
  86.         System.out.println("ScoreManager 處理 博客文章被刪除事件。");  
  87.     }  
  88.   
  89.     @Override  
  90.     public void entryModified(EntryEvent entryevent) {  
  91.         // TODO Auto-generated method stub  
  92.           
  93.         System.out.println("ScoreManager 處理 博客文章被修改事件。");  
  94.           
  95.     }  
  96.   
  97. }  


4. 博客文章事件分發器類

 

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.yanek.event;  
  2.   
  3. import java.util.ArrayList;  
  4. /** 
  5.  * 博客文章事件分發器 
  6.  * @author Administrator 
  7.  * 
  8.  */  
  9. public class EntryEventDispatcher {  
  10.   
  11.     private static EntryEventDispatcher instance = new EntryEventDispatcher();  
  12.     private ArrayList listeners=new ArrayList();  
  13.   
  14.     public static EntryEventDispatcher getInstance() {  
  15.         return instance;  
  16.     }  
  17.   
  18.     private EntryEventDispatcher() {  
  19.           
  20.         String[] observers = PropertyMgr.getProperty("observers").split(",");  
  21.         for(String s : observers) {  
  22.               
  23.             System.out.println(s);  
  24.             try {  
  25.                 this.addListener((EntryListener)(Class.forName(s).newInstance()));  
  26.             } catch (InstantiationException e) {  
  27.                 e.printStackTrace();  
  28.             } catch (IllegalAccessException e) {  
  29.                 e.printStackTrace();  
  30.             } catch (ClassNotFoundException e) {  
  31.                 e.printStackTrace();  
  32.             }  
  33.         }  
  34.           
  35.   
  36.     }  
  37.   
  38.     public synchronized void addListener(EntryListener listener) {  
  39.         System.out.println(":"+listener);  
  40.         if (listener == null) {  
  41.             System.out.println(":"+listener);  
  42.             throw new NullPointerException();  
  43.         } else {  
  44.             listeners.add(listener);  
  45.             return;  
  46.         }  
  47.     }  
  48.   
  49.     public synchronized void removeListener(EntryListener listener) {  
  50.         listeners.remove(listener);  
  51.     }  
  52.   
  53.     public void dispatchEvent(EntryEvent event) {  
  54.         // System.out.println("msgDispatchEvent");  
  55.         int eventType = event.getEventType();  
  56.         long t1=System.currentTimeMillis();  
  57.         System.out.println("kaishi="+t1);  
  58.         for (int i = 0; i < listeners.size(); i++) {  
  59.             try {  
  60.                 EntryListener listener = (EntryListener) listeners.get(i);  
  61.                 String name = listener.getClass().getName();  
  62.                 name = name.substring(name.lastIndexOf('.') + 1);  
  63.   
  64.                 switch (eventType) {  
  65.                 case EntryEvent.ENTRY_ADDED: // 創建博客文章  
  66.                     listener.entryAdded(event);  
  67.                     break;  
  68.   
  69.                 case EntryEvent.ENTRY_DELETED: // 刪除博客文章  
  70.                     listener.entryDeleted(event);   
  71.                     break;  
  72.   
  73.                 case EntryEvent.ENTRY_MODIFIED: //修改 博客文章  
  74.                     listener.entryModified(event);  
  75.                     break;  
  76.   
  77.                 }  
  78.   
  79.             } catch (Exception e) {  
  80.                 // logger.error(e);  
  81.             }  
  82.   
  83.         }  
  84.           
  85.         System.out.println("cost time="+(System.currentTimeMillis()-t1));  
  86.   
  87.         // Profiler.end("msgDispatchEvent");  
  88.     }  
  89. }  


5. 博客文章管理器類

 


 

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.yanek.event;  
  2.   
  3. /** 
  4.  * 博客文章管理器 
  5.  * @author Administrator 
  6.  * 
  7.  */  
  8.   
  9. public class EntryManager {  
  10.   
  11.  /** 
  12.   * @param args 
  13.   */  
  14.  public static void main(String[] args) {  
  15.   
  16.   
  17.   EntryManager eventManager=new EntryManager();  
  18.   Entry entry=new Entry();  
  19.   entry.setId(1);  
  20.   entry.setName("test");  
  21.     
  22.   eventManager.addEntry(entry);  //創建  
  23.     
  24.   eventManager.modifyEntry(entry); //修改  
  25.     
  26.   eventManager.deleteEntry(entry); //刪除  
  27.  }  
  28.    
  29.  public void addEntry(Entry entry) {  
  30.   System.out.println("add entry ...id="+entry.getId());  
  31.     
  32.   // 事件分發  
  33.   EntryEvent event = new EntryEvent(EntryEvent.ENTRY_ADDED, entry, null);  
  34.   EntryEventDispatcher.getInstance().dispatchEvent(event);  
  35.     
  36.  }  
  37.    
  38.  public void deleteEntry(Entry entry) {  
  39.   System.out.println("delete entry ...id="+entry.getId());  
  40.     
  41.   // 事件分發  
  42.   EntryEvent event = new EntryEvent(EntryEvent.ENTRY_DELETED, entry, null);  
  43.   EntryEventDispatcher.getInstance().dispatchEvent(event);  
  44.     
  45.  }  
  46.    
  47.  public void modifyEntry(Entry entry) {  
  48.   System.out.println("modify entry ...id="+entry.getId());  
  49.   // 事件分發  
  50.   EntryEvent event = new EntryEvent(EntryEvent.ENTRY_MODIFIED, entry, null);  
  51.   EntryEventDispatcher.getInstance().dispatchEvent(event);  
  52.     
  53.  }  
  54.   
  55. }  


6. 輔助工具類:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1.   package com.yanek.event;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.Properties;  
  5.   
  6. public class PropertyMgr {  
  7.  private static Properties props = new Properties();  
  8.    
  9.  static {  
  10.   try {  
  11.    props.load(PropertyMgr.class.getClassLoader().getResourceAsStream("com/yanek/event/config.properties"));  
  12.   } catch (IOException e) {  
  13.    e.printStackTrace();  
  14.   }  
  15.  }  
  16.    
  17.  public static String getProperty(String key) {  
  18.   return props.getProperty(key);  
  19.  }  
  20. }  


 7.相關配置文件:

 

配置分發器處理時需要的監聽器實現類的列表。

config.properties

內容如下:

observers=com.yanek.event.IndexManager,com.yanek.event.ScoreManager,com.yanek.event.EmailManager

 

 

 四 測試運行結果:

 

執行: EntryManager 即可看到效果:

 

add entry ...id=1
com.yanek.event.IndexManager
:com.yanek.event.IndexManager@3d3c53
com.yanek.event.ScoreManager
:com.yanek.event.ScoreManager@3d3f58
com.yanek.event.EmailManager
:com.yanek.event.EmailManager@3d425b
kaishi=1404547648004
IndexManager 處理 博客文章被創建事件。
ScoreManager 處理 博客文章被創建事件。
EmailManager 處理 博客文章被創建事件。
cost time=1
modify entry ...id=1
kaishi=1404547648006
IndexManager 處理 博客文章被修改事件。
ScoreManager 處理 博客文章被修改事件。
EmailManager 處理 博客文章被修改事件。
cost time=1
delete entry ...id=1
kaishi=1404547648007
IndexManager 處理 博客文章被刪除事件。
ScoreManager 處理 博客文章被刪除事件。
EmailManager 處理 博客文章被刪除事件。
cost time=0

 

五。關於該方案系統如何實現靈活擴展


假設有如下需求增加了,比如 發表文章,修改文章,刪除文章後需要需要給好友發短信通知或其他相關功能,則只需要再寫一個監聽器的實現類,加入到配置文件中即可。

具體就不寫代碼了,大家可以自己加上測試。

 

 
六、關於資源下載:

地址: http://download.csdn.net/detail/5iasp/7596885

 

 本篇博文參加了CSDN博文大賽,如果您覺得這篇博文不錯,希望您能幫我投一票,謝謝!

投票地址:http://vote.blog.csdn.net/Article/Details?articleid=37054171

學習是一種信仰,分享是一種美德

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章