Spring事件体系包括三个组件:事件,事件监听器,事件广播器。
事件:ApplicationEvent
事件监听器:ApplicationListener,对监听到的事件进行处理。
事件广播器:ApplicationEventMulticaster,将Springpublish的事件广播给所有的监听器。
Spring在ApplicationContext接口的抽象实现类AbstractApplicationContext中完成了事件体系的搭建。
AbstractApplicationContext拥有一个applicationEventMulticaster成员变 量,applicationEventMulticaster提供了容器监听器的注册表。
AbstractApplicationContext在refresh()这个容器启动方法中搭建了事件的基础设施。
try {
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors();
// Register bean processors that intercept bean creation.
registerBeanPostProcessors();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate singletons this late to allow them to access the message source.
beanFactory.preInstantiateSingletons();
// Last step: publish corresponding event.
publishEvent( new ContextRefreshedEvent( this));
}
1、事件广播器的初始化:
private void initApplicationEventMulticaster() throws BeansException {
if (containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME )) {
this.applicationEventMulticaster = (ApplicationEventMulticaster)
getBean( APPLICATION_EVENT_MULTICASTER_BEAN_NAME ,
ApplicationEventMulticaster.class );
if (logger.isInfoEnabled()) {
logger.info("Using ApplicationEventMulticaster ["
+ this. applicationEventMulticaster + "]" );
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster();
if (logger.isInfoEnabled()) {
logger.info("Unable to locate ApplicationEventMulticaster with name '"+
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this .applicationEventMulticaster + "]");
}
}
}
用户可以在配置文件中为容器定义一个自定义的事件广播器,只要实现ApplicationEventMulticaster就可以了,Spring会通过 反射的机制将其注册成容器的事件广播器,如果没有找到配置的外部事件广播器,Spring自动使用 SimpleApplicationEventMulticaster作为事件广播器。
2、注册事件监听器
private void registerListeners () throws BeansException {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
Collection listeners = getBeansOfType(ApplicationListener.class,true,false).values();
for (Iterator it = listeners.iterator(); it.hasNext();) {
addListener((ApplicationListener) it.next());
}
}
protected void addListener(ApplicationListener listener) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
Spring根据反射机制,使用
ListableBeanFactory的
getBeansOfType方法,从BeanDefinitionRegistry中找出所有实现 org.springframework.context.ApplicationListener的Bean,将它们注册为容器的事件监听器,实际的操作就是将其添加到事件广播器所提供的监听器注册表中。
3、发布事件
public void publishEvent(ApplicationEvent event) {
Assert. notNull(event, "Event must not be null");
if (logger .isDebugEnabled()) {
logger .debug("Publishing event in context ["
+ getDisplayName() + "]: " + event);
}
getApplicationEventMulticaster(). multicastEvent(event);
if (this .parent != null) {
this .parent .publishEvent(event);
}
}
在AbstractApplicationContext的publishEvent方法中, Spring委托ApplicationEventMulticaster将事件通知给所有的事件监听器
4、Spring默认的事件广播器SimpleApplicationEventMulticaster
public void multicastEvent( final ApplicationEvent event) {
for (Iterator it = getApplicationListeners().iterator(); it.hasNext();) {
final ApplicationListener listener = (ApplicationListener) it.next();
getTaskExecutor().execute( new Runnable() {
public void run() {
listener.onApplicationEvent(event);
}
});
}
}
遍历注册的每个监听器,并启动来调用每个监听器的onApplicationEvent方法。
由于SimpleApplicationEventMulticaster的taskExecutor的实现类是
SyncTaskExecutor,因此,事件监听器对事件的处理,是同步进行的。
从代码可以看出,applicationContext.publishEvent()方法,需要同步等待各个监听器处理完之后,才返回。
也就是说,Spring提供的事件机制,默认是同步的。如果想用异步的,可以自己实现ApplicationEventMulticaster接口,并在Spring容器中注册id为
applicationEventMulticaster的Bean。
例子:
Spring发布事件之后,所有注册的事件监听器,都会收到该事件,因此,事件监听器在处理事件时,需要先判断该事件是否是自己关心的。
例子:
public class AsyncApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
private TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
public void setTaskExecutor(TaskExecutor taskExecutor) {
this.taskExecutor = (taskExecutor != null ? taskExecutor : new SimpleAsyncTaskExecutor());
}
protected TaskExecutor getTaskExecutor() {
return this.taskExecutor;
}
@SuppressWarnings("unchecked")
public void multicastEvent(final ApplicationEvent event) {
for (Iterator<ApplicationListener> it = getApplicationListeners().iterator(); it.hasNext();) {
final ApplicationListener listener = it.next();
getTaskExecutor().execute(new Runnable() {
public void run() {
listener.onApplicationEvent(event);
}
});
}
}
}
spring配置:
<bean id="applicationEventMulticaster"
class="com.alibaba.chj.event.AsyncApplicationEventMulticaster" />
Spring发布事件之后,所有注册的事件监听器,都会收到该事件,因此,事件监听器在处理事件时,需要先判断该事件是否是自己关心的。
Sping事件体系所使用的设计模式是:观察者模式。
ApplicationListener是观察者接口,接口中定义了onApplicationEvent方法,该方法的作用是对ApplicationEvent事件进行处理。