spring的事件機制使用的是觀察者模式
觀察者模式學習http://www.runoob.com/design-pattern/observer-pattern.html
ApplicationEvent : 具體的事件對象,充當介質
這是一個抽象類,spring提供了幾種實現 ApplicationContextEvent,ContextClosedEvent,ContextRefreshedEvent,ContextStartedEvent,ContextStoppedEvent和RequestHandledEvent
ApplicationEvent 源碼如下:
public abstract class ApplicationEvent extends EventObject {
/** use serialVersionUID from Spring 1.2 for interoperability */
private static final long serialVersionUID = 7099057708183571937L;
/** System time when the event happened */
private final long timestamp;
/**
* Create a new ApplicationEvent.
* @param source the component that published the event (never <code>null</code>)
*/
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
/**
* Return the system time in milliseconds when the event happened.
*/
public final long getTimestamp() {
return this.timestamp;
}
}
ApplicationListener : 觀察者,觀察和處理具體事件
源碼如下:
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
ApplicationEventMulticaster : 觀察者模式中的Subject ,負責管理觀察者,發佈事件
源碼如下:
public interface ApplicationEventMulticaster {
/**
* Add a listener to be notified of all events.
* @param listener the listener to add
*/
void addApplicationListener(ApplicationListener listener);
/**
* Add a listener bean to be notified of all events.
* @param listenerBeanName the name of the listener bean to add
*/
void addApplicationListenerBean(String listenerBeanName);
/**
* Remove a listener from the notification list.
* @param listener the listener to remove
*/
void removeApplicationListener(ApplicationListener listener);
/**
* Remove a listener bean from the notification list.
* @param listenerBeanName the name of the listener bean to add
*/
void removeApplicationListenerBean(String listenerBeanName);
/**
* Remove all listeners registered with this multicaster.
* <p>After a remove call, the multicaster will perform no action
* on event notification until new listeners are being registered.
*/
void removeAllListeners();
/**
* Multicast the given application event to appropriate listeners.
* @param event the event to multicast
*/
void multicastEvent(ApplicationEvent event);
}
ApplicationEventMulticaster spring中提供了默認的實現SimpleApplicationEventMulticaster,在spring的上下文application中有該類的bean,調用application的publishEvent方法時,就是直接調用該類的multicastEvent方法
publishEvent如下:
public void publishEvent(ApplicationEvent event) {
Assert.notNull(event, "Event must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Publishing event in " + getDisplayName() + ": " + event);
}
getApplicationEventMulticaster().multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
}
ApplicationEventMulticaster 的multicastEvent會一次調用註冊的觀察者的onApplicationEvent方法
multicastEvent實現如下:
public void multicastEvent(final ApplicationEvent event) {
for (final ApplicationListener listener : getApplicationListeners(event)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@SuppressWarnings("unchecked")
public void run() {
listener.onApplicationEvent(event);
}
});
}
else {
listener.onApplicationEvent(event);
}
}
}
使用spring事件機制的例子 郵件發送提示
1.定義事件
public class MailSendEvent extends ApplicationEvent {
public MailSendEvent(Object source, String fromAddress, String toAddress) {
super(source);
this.fromAddress = fromAddress;
this.toAddress = toAddress;
}
private static final long serialVersionUID = 1L;
private String fromAddress;
private String toAddress;
public String getFromAddress() {
return fromAddress;
}
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
public String getToAddress() {
return toAddress;
}
public void setToAddress(String toAddress) {
this.toAddress = toAddress;
}
@Override
public String toString() {
return fromAddress + " Send Mail to " + toAddress;
}
}
2.定義觀察者
public class MailSendEventListener implements ApplicationListener<MailSendEvent> {
public void onApplicationEvent(MailSendEvent event) {
System.out.println("發生一個郵件發送的事件:" + event);
}
}
3.定義觸發事件發生的地方,即發送郵件的地方
public class MailBean implements ApplicationContextAware {
private String fromAddress;
private String toAddress;
ApplicationContext applicationContext;
public MailBean(String fromAddress, String toAddress) {
this.fromAddress = fromAddress;
this.toAddress = toAddress;
}
public void sendMail() {
System.out.println(fromAddress + " Send Mail to " + toAddress);
MailSendEvent event = new MailSendEvent(applicationContext, fromAddress, toAddress);
applicationContext.publishEvent(event);
}
public String getFromAddress() {
return fromAddress;
}
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
public String getToAddress() {
return toAddress;
}
public void setToAddress(String toAddress) {
this.toAddress = toAddress;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
4.配置文件
<bean class="com.yang.spring.event.MailSendEventListener" />
<bean id="mailTest" class="com.yang.spring.event.MailBean" init-method="sendMail">
<constructor-arg index="0" value="ttt"></constructor-arg>
<constructor-arg index="1" value="yyy"></constructor-arg>
</bean>
5.測試
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
}
6.測試結果
ttt Send Mail to yyy
發生一個郵件發送的事件:ttt Send Mail to yyy