这一节我们来看一下容器启动时messageSource的初始化和监听器的初始化。
这一节主要的源码分四块:
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
其中onRefresh方法是留给用户自定义的,所以这里主要看一下其他三个方法的源码。
initMessageSource
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判断beanFactory中是否有messageSource的beanDefinition
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
//如果有,且满足条件,则设置parent
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
……日志
}
else {
// 如果没有则初始化,并设置parent,最后注册到beanFactory中,这里的parent就是容器的parent,一般为null
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
……日志
}
}
initApplicationEventMulticaster
protected void initApplicationEventMulticaster() {
//判断beanFactory中是否存在applicationEventMulticaster的beanDefinition
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
……日志
}
else {
//如果没有则初始化,并注册
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
……日志
}
}
registerListeners
在分析registerListeners源码之前,我们先来回顾一下prepareRefresh中的一段源码:
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.earlyApplicationEvents = new LinkedHashSet<>();
通过上面的代码可以看出,spring容器会初始化两个set,earlyApplicationListeners和earlyApplicationEvents
下面我们来看一下registerListeners的源码:
protected void registerListeners() {
//如果在spring容器初始化前earlyApplicationListeners中已经有Listener了,那么这里会执行
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
//检测beanDefinition中是否有ApplicationListener的子类如果有,则执行
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
//applicationEventMulticaster为上一步监听器初始化的时候
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
//如果earlyApplicationEvents中存在已经发布的事件,则直接执行
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
//在容器初始化后,earlyApplicationEvents又会变成null
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
上面这段代码前两步很简单,就是将定义的监听器注册到事件的广播中,但是这里有两个疑问:
- earlyApplicationEvents在什么情况下会有数据
- 在消息发布后,监听器是如何运作的
要理解这两个问题,我们需要看一下publishEvent方法的源码:
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
//这里会先判断一下event的类型,并最终会转换成ApplicationEvent
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
}
}
/**
* 查看earlyApplicationEvents是不是为空,如果是,那么直接执行事件的监听逻辑
* 这里为空情况有两种:
* 1. 在容器启动时prepareRefresh之前
* 2. 在registerListeners之后,因为在这一步,会将earlyApplicationEvents置空
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
//让父容器也去消费该事件
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
从上面的代码,我们知道了第一个问题的答案,至于第二个问题,我们进入执行监听逻辑的代码
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType):
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
//解析出这个事件的ResolvableType
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
//再根据这个type获取到所有监听这个类型的event的listener(通过onApplicationEvent方法的参数去判断),并且执行
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}