轉載:http://blog.csdn.net/5iasp/article/details/37054171
謝謝博主
=======================================================================================================
文章標題:關於Java中事件分發和監聽機制實現的代碼實例
文章地址: http://blog.csdn.net/5iasp/article/details/37054171
作者: javaboy2012
Email:[email protected]
qq: 1046011462
一、場景假設
假設有博客系統中需要實現如下功能:
系統中用戶發佈文章,修改文章,刪除文章時,需要一些相關的操作需要執行。
發佈文章後,給好友發送郵件通知,給用戶加積分,對文章做全文索引。
修改文章後,給好友發送郵件修改通知,給用戶加積分,對文章重新做全文索引。
刪除文章後,給好友發送郵件修改通知,給用戶減少積分,對文章重新做全文索引。
二、相關的概念解析
分析如上場景,可以採用事件分發和監聽機制來實現。
事件分發和監聽有如下幾個概念:
事件源:觸發事件的對象 如上場景中我們把實體對象作爲事件源,發佈的文章就是事件源
事件: 對事件源的操作產生事件,例如 發表文章 修改文章,刪除文章這些操作就會觸發相關的 文章被髮表事件,文章被刪除事件,文章被修改事件
事件監聽器:對事件源各種事件觸發執行行爲的抽象,包括接口和若干實現類。
比如: 接口需要定義事件源相關事件觸發時需要實現的操作接口。
事件分發器:事件分發器主要處理事件的分發和事件監聽器的管理,註冊和刪除事件監聽器等。
三、 代碼示例
項目結構:
根據上述概念相關代碼如下:
包括如下代碼
1. 博客文章類 屬於事件源
- package com.yanek.event;
- /**
- * 博客文章
- * @author Administrator
- *
- */
- public class Entry {
- public long getId() {
- return id;
- }
- public void setId(long id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- private long id; // 編號
- private String name; //標題
- }
2. 博客文章事件類 屬於事件對象
其中定義了事件的類型和事件源,事件參數
- package com.yanek.event;
- import java.util.Collections;
- import java.util.Date;
- import java.util.Map;
- /**
- * 博客文章事件
- * @author Administrator
- *
- */
- public class EntryEvent
- {
- public static final int ENTRY_ADDED = 100; //事件類型:博客文章被創建
- public static final int ENTRY_DELETED = 101;//事件類型:博客文章被刪除
- public static final int ENTRY_MODIFIED = 102;//事件類型:博客文章被修改
- private int eventType; //事件類型
- private Entry entry; //博客文章對象
- private Date date; //事件觸發日期
- private Map params; //事件輔助參數
- public EntryEvent(int eventType, Entry entry, Map params) {
- this.eventType = eventType;
- this.entry = entry;
- this.params = params != null ? Collections.unmodifiableMap(params)
- : null;
- date = new Date();
- }
- public int getEventType() {
- return eventType;
- }
- public Entry getEntry() {
- return entry;
- }
- public Map getParams() {
- return params;
- }
- public Date getDate() {
- return date;
- }
- }
3. 事件監聽器接口和實現類:
定義各種事件發生時需要處理的接口方法
- package com.yanek.event;
- /**
- * 博客文章監聽器接口
- * @author Administrator
- *
- */
- public interface EntryListener
- {
- /**
- * 博客文章被創建
- * @param entryevent
- */
- public abstract void entryAdded(EntryEvent entryevent);
- /**
- * 博客文章被刪除
- * @param entryevent
- */
- public abstract void entryDeleted(EntryEvent entryevent);
- /**
- * 博客文章被修改
- * @param entryevent
- */
- public abstract void entryModified(EntryEvent entryevent);
- }
事件監聽器接口的實現類:
實現場景中的三類操作,監聽器接口實現包括如下三個類實現
IndexManager 索引管理器類
ScoreManager 積分管理器類
EmailManager 郵件管理器類
三個類都實現監聽器接口EntryListener。具體代碼如下:
- package com.yanek.event;
- /**
- * 郵件管理器
- * @author Administrator
- *
- */
- public class EmailManager implements EntryListener{
- @Override
- public void entryAdded(EntryEvent entryevent) {
- System.out.println("EmailManager 處理 博客文章被創建事件。");
- }
- @Override
- public void entryDeleted(EntryEvent entryevent) {
- System.out.println("EmailManager 處理 博客文章被刪除事件。");
- }
- @Override
- public void entryModified(EntryEvent entryevent) {
- System.out.println("EmailManager 處理 博客文章被修改事件。");
- }
- }
- package com.yanek.event;
- /**
- * 索引管理器
- * @author Administrator
- *
- */
- public class IndexManager implements EntryListener {
- @Override
- public void entryAdded(EntryEvent entryevent) {
- System.out.println("IndexManager 處理 博客文章被創建事件。");
- }
- @Override
- public void entryDeleted(EntryEvent entryevent) {
- // TODO Auto-generated method stub
- System.out.println("IndexManager 處理 博客文章被刪除事件。");
- }
- @Override
- public void entryModified(EntryEvent entryevent) {
- // TODO Auto-generated method stub
- System.out.println("IndexManager 處理 博客文章被修改事件。");
- }
- }
- package com.yanek.event;
- /**
- * 積分管理器
- * @author Administrator
- *
- */
- public class ScoreManager implements EntryListener {
- @Override
- public void entryAdded(EntryEvent entryevent) {
- System.out.println("ScoreManager 處理 博客文章被創建事件。");
- }
- @Override
- public void entryDeleted(EntryEvent entryevent) {
- // TODO Auto-generated method stub
- System.out.println("ScoreManager 處理 博客文章被刪除事件。");
- }
- @Override
- public void entryModified(EntryEvent entryevent) {
- // TODO Auto-generated method stub
- System.out.println("ScoreManager 處理 博客文章被修改事件。");
- }
- }
4. 博客文章事件分發器類
- package com.yanek.event;
- import java.util.ArrayList;
- /**
- * 博客文章事件分發器
- * @author Administrator
- *
- */
- public class EntryEventDispatcher {
- private static EntryEventDispatcher instance = new EntryEventDispatcher();
- private ArrayList listeners=new ArrayList();
- public static EntryEventDispatcher getInstance() {
- return instance;
- }
- private EntryEventDispatcher() {
- String[] observers = PropertyMgr.getProperty("observers").split(",");
- for(String s : observers) {
- System.out.println(s);
- try {
- this.addListener((EntryListener)(Class.forName(s).newInstance()));
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
- public synchronized void addListener(EntryListener listener) {
- System.out.println(":"+listener);
- if (listener == null) {
- System.out.println(":"+listener);
- throw new NullPointerException();
- } else {
- listeners.add(listener);
- return;
- }
- }
- public synchronized void removeListener(EntryListener listener) {
- listeners.remove(listener);
- }
- public void dispatchEvent(EntryEvent event) {
- // System.out.println("msgDispatchEvent");
- int eventType = event.getEventType();
- long t1=System.currentTimeMillis();
- System.out.println("kaishi="+t1);
- for (int i = 0; i < listeners.size(); i++) {
- try {
- EntryListener listener = (EntryListener) listeners.get(i);
- String name = listener.getClass().getName();
- name = name.substring(name.lastIndexOf('.') + 1);
- switch (eventType) {
- case EntryEvent.ENTRY_ADDED: // 創建博客文章
- listener.entryAdded(event);
- break;
- case EntryEvent.ENTRY_DELETED: // 刪除博客文章
- listener.entryDeleted(event);
- break;
- case EntryEvent.ENTRY_MODIFIED: //修改 博客文章
- listener.entryModified(event);
- break;
- }
- } catch (Exception e) {
- // logger.error(e);
- }
- }
- System.out.println("cost time="+(System.currentTimeMillis()-t1));
- // Profiler.end("msgDispatchEvent");
- }
- }
5. 博客文章管理器類
- package com.yanek.event;
- /**
- * 博客文章管理器
- * @author Administrator
- *
- */
- public class EntryManager {
- /**
- * @param args
- */
- public static void main(String[] args) {
- EntryManager eventManager=new EntryManager();
- Entry entry=new Entry();
- entry.setId(1);
- entry.setName("test");
- eventManager.addEntry(entry); //創建
- eventManager.modifyEntry(entry); //修改
- eventManager.deleteEntry(entry); //刪除
- }
- public void addEntry(Entry entry) {
- System.out.println("add entry ...id="+entry.getId());
- // 事件分發
- EntryEvent event = new EntryEvent(EntryEvent.ENTRY_ADDED, entry, null);
- EntryEventDispatcher.getInstance().dispatchEvent(event);
- }
- public void deleteEntry(Entry entry) {
- System.out.println("delete entry ...id="+entry.getId());
- // 事件分發
- EntryEvent event = new EntryEvent(EntryEvent.ENTRY_DELETED, entry, null);
- EntryEventDispatcher.getInstance().dispatchEvent(event);
- }
- public void modifyEntry(Entry entry) {
- System.out.println("modify entry ...id="+entry.getId());
- // 事件分發
- EntryEvent event = new EntryEvent(EntryEvent.ENTRY_MODIFIED, entry, null);
- EntryEventDispatcher.getInstance().dispatchEvent(event);
- }
- }
6. 輔助工具類:
- package com.yanek.event;
- import java.io.IOException;
- import java.util.Properties;
- public class PropertyMgr {
- private static Properties props = new Properties();
- static {
- try {
- props.load(PropertyMgr.class.getClassLoader().getResourceAsStream("com/yanek/event/config.properties"));
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static String getProperty(String key) {
- return props.getProperty(key);
- }
- }
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