這次的内容是上圖中的第08步。
前言
先來看看前面幾篇文章都做了什麼:
`01-prepareRefresh()`: `earlyApplicationListeners`、`applicationListeners` 、`initPropertySources()`、`validateRequiredProperties`
`02-obtainFreshBeanFactory()`: `refreshBeanFactory`
`03-prepareBeanFactory()`: `ignoreDependencyInterface`、`setBeanExpressionResolver`、`registerResolvableDependency`、`Environment`
`04-postProcessBeanFactory()`: 具體實作類的特殊邏輯(`Servlet` 等)
`05-invokeBeanFactoryPostProcessors()`: 可能發生的對 `BeanFactory/BeanDefinitionRegistry` 的修改操作
`06-registerBeanPostProcessors()`: 所有的 `BeanPostProcessor` 已經被執行個體化并且注冊到了 `BeanFactory` 中
`07-initMessageSource()`: `MessageSource` 已經就緒了,可以支援國際化(`I18N`)資源處理了
上一個步驟是初始化 MessageSource 以支援 I18N, 依然是在為 Bean 的建立做準備工作。
本文要介紹的 initApplicationEventMulticaster() 依然是在給 Bean 的建立做準備工作。本文的内容也是非常非常簡單。
initApplicationEventMulticaster() 就是初始化 ApplicationEventMulticaster,那麼什麼是 ApplicationEventMulticaster 呢?
前置知識
先來了解下 ApplicationEventMulticaster、ApplicationContext 和 ApplicationEventPublisher 這三個元件的關系。
ApplicationEventMulticaster
ApplicationEventMulticaster 是 spring 中事件功能的重要元件。可以通過他注冊/删除監聽器、釋出事件。接口聲明如下:
public interface ApplicationEventMulticaster {
void addApplicationListener(ApplicationListener<?> listener);
// 通過 beanName 添加監聽器,避免過早初始化 Bean
void addApplicationListenerBean(String listenerBeanName);
void removeApplicationListener(ApplicationListener<?> listener);
void removeApplicationListenerBean(String listenerBeanName);
void removeApplicationListeners(Predicate<ApplicationListener<?>> predicate);
void removeApplicationListenerBeans(Predicate<String> predicate);
void removeAllListeners();
// 釋出事件的接口
void multicastEvent(ApplicationEvent event);
// 釋出事件的接口
void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);
}
SimpleApplicationEventMulticaster
再來看看 ApplicationEventMulticaster 的一個簡單實作。
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
@Nullable
private Executor taskExecutor;
@Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}
// 省略其他代碼。。。
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
// 擷取到對目前事件感興趣的 `ApplicationListener`
// 挨個回調: 也就是監聽器被回調了
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
} else {
invokeListener(listener, event);
}
}
}
}
如果你給了他一個線程池,那他就使用線程池異步釋出事件,否則就在目前調用線程上釋出事件。
ApplicationEventPublisher
如果隻是要釋出事件的話,直接使用 ApplicationEventPublisher 接口就可以了,沒必要使用 ApplicationContext。
public interface ApplicationEventPublisher {
void publishEvent(Object event);
}
其實 ApplicationContext 就繼承了 ApplicationEventPublisher,那麼 ApplicationContext 的是怎麼實作事件的釋出的呢?
在 ApplicationContext 的實作中,實際上是委托給 ApplicationEventMulticaster 去釋出事件的。
比如 AbstractApplicationContext,就是将事件的釋出委托給了内部維護的一個 ApplicationEventMulticaster。
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
@Nullable
private ApplicationEventMulticaster applicationEventMulticaster;
@Override
public void addApplicationListener(ApplicationListener<?> listener) {
Assert.notNull(listener, "ApplicationListener must not be null");
if (this.applicationEventMulticaster != null) {
this.applicationEventMulticaster.addApplicationListener(listener);
}
this.applicationListeners.add(listener);
}
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
// 省略其他代碼
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
// 省略其他代碼
}
}
initApplicationEventMulticaster
現在看看容器重新整理的第 8 步的源碼:
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
@Nullable
private ApplicationEventMulticaster applicationEventMulticaster;
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 1. 如果目前 BeanFactory 中已經有了名為 `applicationEventMulticaster` 的 Bean
// 就給this.applicationEventMulticaster指派
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
// 2. 如果目前 BeanFactory 中還沒有名為 `applicationEventMulticaster` 的 Bean
else {
// new 一個 SimpleApplicationEventMulticaster 類型的 ApplicationEventMulticaster 實作
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
// 剛剛 new 出來的對象注冊到 BeanFactory 中
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
}