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