java 觀察者、事件機制和Spring 事件分發 精華一頁紙

事件處理一般都採用類似觀察者模式, java util自帶了觀察者模式的接口

1、觀察者模式接口


關於觀察者這個模式, 可以參見本博《設計模式 精華一頁紙》, JDK 提供的這個接口, 可以方便的進行開發
java.util.Observable -- 事件發佈者 (目標)
java.util.Observer -- 事件監聽者 (觀察者)

2、事件處理接口


EventObject - 事件對象
EventListener - 事件監聽對象

接口雖然簡單, 但java的事件都是基於如上的接口, 比如典型 GUI 的awt事件

要完成一個完整的事件模型 就需要結合 觀察者模式 + 事件處理接口,即包含三個部分:事件、事件發佈者、監聽者

3、Spring 的事件派發模型


事件 ApplicationEvent -> 繼承 EventObject
監聽者 ApplicationListener -> 繼承 EventListener
事件管理者/發佈者 ApplicationEventPublisher | ApplicationEventMulticaster, 這是JDK 事件未提供的模塊

I、實例
a、事件
public class LogEvent extends ApplicationEvent{
public LogEvent(Log source) {
super(source);
}
@Override
public Log getSource(){
return (Log)super.getSource();
}
}

b、監聽者
public class LogListener implements ApplicationListener<LogEvent>{
@Override
public void onApplicationEvent(LogEvent event) {
System.out.println("get event : " + event.getSource());
}
}

c、事件發佈者
public class LogPublisher implements ApplicationEventPublisher{
private List<ApplicationListener<ApplicationEvent>> listeners = new LinkedList<ApplicationListener<ApplicationEvent>>();
@Override
public void publishEvent(ApplicationEvent event) {
for(ApplicationListener<ApplicationEvent> listener : listeners)
listener.onApplicationEvent(event);
}
public void addListener(ApplicationListener<ApplicationEvent> listener){
listeners.add(listener);
}
}

應用
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的體系
常用的事件

事件發佈者/管理者
ApplicationEventPublisher
ApplicationEventMulticaster
-- AbstractApplicationContext
-- XXXApplicationContext

監聽者
ApplicationListener
SmartApplicationListener -- 可以支持按順序調用

III、增強調用(結合 Spring 任務調度機制)
因爲Spring 觀察者模式採用的是 推的方式,所以 如果某個任務執行很慢, 就會卡住, 所以Spring提供了異步調用的機制, SimpleApplicationEventMulticaster, 通知任務都是以異步方式執行
<task:executor id="taskExecutor" pool-size="1-4" queue-capacity="128" />
<bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster">
<property name="taskExecutor" ref="taskExecutor"/>
</bean>

默認情況下,如果有配置的 applicationEventMulticaster, 按照約定的默認名稱獲取發佈者, 如果沒有 代碼自動new一個 發佈者。這種默認值是 很多配置框架的一個原則-- 約定優於配置。

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