事件處理一般都采用類似觀察者模式, java util自帶了觀察者模式的接口
1淘钟、觀察者模式接口
關(guān)于觀察者這個(gè)模式, 可以參見本博《設(shè)計(jì)模式 精華一頁(yè)紙》, JDK 提供的這個(gè)接口, 可以方便的進(jìn)行開發(fā)
java.util.Observable -- 事件發(fā)布者 (目標(biāo))
java.util.Observer -- 事件監(jiān)聽者 (觀察者)
2、事件處理接口
EventObject - 事件對(duì)象
EventListener - 事件監(jiān)聽對(duì)象
接口雖然簡(jiǎn)單, 但java的事件都是基于如上的接口, 比如典型 GUI 的awt事件
要完成一個(gè)完整的事件模型 就需要結(jié)合 觀察者模式 + 事件處理接口,即包含三個(gè)部分:事件冗酿、事件發(fā)布者、監(jiān)聽者
3络断、Spring 的事件派發(fā)模型
事件 ApplicationEvent -> 繼承 EventObject
監(jiān)聽者 ApplicationListener -> 繼承 EventListener
事件管理者/發(fā)布者 ApplicationEventPublisher | ApplicationEventMulticaster, 這是JDK 事件未提供的模塊
I裁替、實(shí)例
a、事件
public class LogEvent extends ApplicationEvent{
public LogEvent(Log source) {
super(source);
}
@Override
public Log getSource(){
return (Log)super.getSource();
}
}
b貌笨、監(jiān)聽者
public class LogListener implements ApplicationListener{
@Override
public void onApplicationEvent(LogEvent event) {
System.out.println("get event : " + event.getSource());
}
}
c弱判、事件發(fā)布者
public class LogPublisher implements ApplicationEventPublisher{
private List> listeners = new LinkedList>();
@Override
public void publishEvent(ApplicationEvent event) {
for(ApplicationListener listener : listeners)
listener.onApplicationEvent(event);
}
public void addListener(ApplicationListener listener){
listeners.add(listener);
}
}
應(yīng)用
noSpring
ApplicationEvent event = new LogEvent(log);
ApplicationListener listener = new LogListener();
LogPublisher pub = new LogPublisher();
pub.addListener(listener);
pub.publishEvent(event);
Spring
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
context.addApplicationListener(listener);
context.publishEvent(event);
II、Spring的體系
常用的事件
事件發(fā)布者/管理者
ApplicationEventPublisher
ApplicationEventMulticaster
-- AbstractApplicationContext
-- XXXApplicationContext
監(jiān)聽者
ApplicationListener
SmartApplicationListener -- 可以支持按順序調(diào)用
III锥惋、增強(qiáng)調(diào)用(結(jié)合 Spring 任務(wù)調(diào)度機(jī)制)
因?yàn)镾pring 觀察者模式采用的是 推的方式,所以 如果某個(gè)任務(wù)執(zhí)行很慢, 就會(huì)卡住, 所以Spring提供了異步調(diào)用的機(jī)制, SimpleApplicationEventMulticaster, 通知任務(wù)都是以異步方式執(zhí)行
默認(rèn)情況下,如果有配置的 applicationEventMulticaster, 按照約定的默認(rèn)名稱獲取發(fā)布者, 如果沒(méi)有 代碼自動(dòng)new一個(gè) 發(fā)布者昌腰。這種默認(rèn)值是 很多配置框架的一個(gè)原則-- 約定優(yōu)于配置。