關於事件監聽我們需要知道的一些基礎知識。
a)事件三要素(who when what):
source -- 事件源 when -- 事件發生時間 message -- 事件主題消息,即希望通過事件傳遞出去的信息
b)事件模型的構成:
event -- 事件 source -- 事件源 listener -- 事件監聽器
c)事件流轉過程:
(1)事件源注冊監聽器 -> (2)事件發生 -> (3)通知監聽器 -> (4)監聽器處理
那么基於以上背景知識,我們來是實現一個簡單的監聽器,並測試一下事件監聽的完整流程。
根據事件三要素設計出一個簡單合理的事件載體:Event
public interface Event extends Serializable { Object getSource(); Date getWhen(); String getMessage(); /** * 事件回調方法 */ void callback(); }
事件實現:MyEvent

public class MyEvent implements Event { private Log log = LogFactory.getLog(getClass()); private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); private Object source; private Date when; private String message; @Override public Object getSource() { return source; } public void setSource(Object source) { this.source = source; } @Override public Date getWhen() { return when; } public void setWhen(Date when) { this.when = when; } @Override public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @Override public void callback() { log.info(toString()); } @Override public String toString() { return "source: " + getSource() + ", message: " + getMessage() + ", when: " + sdf.format(getWhen()); } }
監聽器接口:EventListener
public interface EventListener { /** * 事件觸發 * @param event */ void handleEvent(Event event); }
監聽器實現:MyListener
public class MyListener implements EventListener { @Override public void handleEvent(Event event) { event.callback(); } }
事件源接口:EventSource
public interface EventSource { /** * 增加監聽器 * @param listener */ void addListener(EventListener listener); /** * 通知監聽器 */ void notifyListener(); }
編寫測試的事件源:MySource
public class MySource implements EventSource { private List<EventListener> listeners = new ArrayList<EventListener>(); private int value; @Override public void addListener(EventListener listener) { listeners.add(listener); } @Override public void notifyListener() { for (EventListener listener : listeners) { MyEvent event = new MyEvent(); event.setSource(this); event.setWhen(new Date()); event.setMessage("setValue " + value); listener.handleEvent(event); } } public int getValue() { return value; } public void setValue(int value) { this.value = value; notifyListener(); } @Test public void testEventListener() { MySource source = new MySource(); source.addListener(new MyListener()); source.setValue(100); } }
測試輸出:
[INFO]-[Event-callback(50)]: source: com.lichmama.test.listen.MySource@119126ab, message: setValue 100, when: 2018-05-01 02:52:13
*PS:監聽器模式和觀察者模式看起來很像,不過在事件模型的設置上有些許差別。在觀察者模式中並沒有Event這個角色,或者說它被合並到Observable角色中了,即整合了事件源與事件。