在Spring Boot 初始化中講過,完成SpringApplication
構造後,調用run方法,會進行SpringApplicationRunListener
的初始化,通過debug得到一個默認SpringApplicationRunListener
實現
查看源代碼 (構造函數)
public EventPublishingRunListener(SpringApplication application, String[] args) {
this.application = application;
this.args = args;
// 實例化了一個 SimpleApplicationEventMulticaster
this.initialMulticaster = new SimpleApplicationEventMulticaster();
// 並將 SpringApplication中的監聽器全部放到了 SimpleApplicationEventMulticaster 中
for (ApplicationListener<?> listener : application.getListeners()) {
this.initialMulticaster.addApplicationListener(listener);
}
}
這裏看下 SimpleApplicationEventMulticaster 的繼承關係
事件體系
- ApplicationEvent(事件)
- ApplicationListener(消息接收者)
- ApplicationEventMulticaster (消息廣播)
事件體系的初始化
在SpringApplication的refreshContext 中進行,具體代碼在
AbstractApplicationContext.refresh()
代碼塊見如下,調用initApplicationEventMulticaster()來完成事件體系的搭建
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
}
beanFactory 用戶可以在自定義廣播事件,Spring 會將其設置爲 自身的 事件廣播,沒有發現自定義的廣播,會使用默認的 SimpleApplicationEventMulticaster
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
// 事件註冊
protected void registerListeners() {
// Register statically specified listeners first.
// 註冊指定的Bean
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 實際調用 DefaultListableBeanFactory 中 getBeanNamesForType得到自定義的 ApplicationListenerbean進行事件註冊
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 廣播早期的事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
廣播事件
protected void publishEvent(Object event, ResolvableType eventType) {
...
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
// 省略代碼
...
}
廣播事件通過調用 ApplicationEventMulticaste
r的 multicastEvent
來實現。
執行事件
源碼較長截取部分
@Override
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
invokeListener(listener, event);
}
});
}
else {
invokeListener(listener, event);
}
}
}
invokeListener的核心代碼 listener.onApplicationEvent(event);
遍歷註冊的每個監聽器,並啓動來調用每個監聽器的onApplicationEvent方法。
代碼中看到 應用到了 Executor 有可用的executor 會使用併發的模式執行事件,SimpleApplicationEventMulticaster內,並沒有實現線程池,所以使用同步的方式執行事件,需要異步配置的,需要去實現線程池。