关联博文:
AbstractApplicationContext中refresh方法详解
Spring中refresh分析之prepareRefresh方法详解
Spring中refresh分析之obtainFreshBeanFactory方法详解
Spring中refresh分析之prepareBeanFactory方法详解
Spring中refresh分析之postProcessBeanFactory方法详解
Spring中refresh分析之invokeBeanFactoryPostProcessors方法详解
Spring中refresh分析之registerBeanPostProcessors方法详解
Spring中refresh分析之initMessageSource方法详解
Spring中refresh分析之initApplicationEventMulticaster方法详解
Spring中refresh分析之onRefresh方法详解
Spring中refresh分析之registerListeners方法详解
Spring中refresh分析之finishBeanFactoryInitialization方法详解
Spring中refresh分析之finishRefresh方法详解
接上文Spring中refresh分析之onRefresh方法详解我们分析过onRefresh后,本文分析registerListeners方法。
顾名思义,注册监听器。将会获取AbstractApplicationContext
的applicationListeners
和容器中的ApplicationListener进行注册,最后会尝试将earlyApplicationEvents广播出去。
protected void registerListeners() {
// Register statically specified listeners first.
//获取的是成员applicationListeners
for (ApplicationListener<?> listener : getApplicationListeners()) {
// 获取SimpleApplicationEventMulticaster触发其方法
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 从容器中获取ApplicationListener
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
// 获取SimpleApplicationEventMulticaster触发其方法-这里放的是beanName
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
// 发布早期事件,本文这里为空
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
//设置为null,这个很重要
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
// 如果早期/渴望的事件存在,则将其广播出去
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
方法逻辑梳理如下:
- 获取
AbstractApplicationContext
的成员监听器然后遍历进行注册; - 从容器中获取
ApplicationListener
然后进行遍历记录监听器名称放到this.defaultRetriever.applicationListenerBeans
; - earlyApplicationEvents赋予earlyEventsToProcess 然后重新将置为null。如果earlyEventsToProcess不为空则进行遍历挨个进行事件广播。
这里getApplicationListeners()
获取的applicationListeners
是AbstractApplicationContext
的成员private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
。这些监听器是在refresh方法前的prepareContext方法中注册进来的。
earlyApplicationEvents我们在哪里看到过呢?仍然是prepareRefresh方法中,对其进行了初始化是一个空的LinkedHashSet。
通过应用上下文广播事件时,如果事件广播器还没有实例化好,那么事件会被存放在earlyApplicationEvents中。当事件广播器实例化好之后,earlyApplicationEvents会被指向null,其维护的早期事件会被广播出去。
addApplicationListener
我们继续看SimpleApplicationEventMulticaster
的addApplicationListener
方法,看是如何对监听器进行注册的。
@Override
public void addApplicationListener(ApplicationListener<?> listener) {
synchronized (this.retrievalMutex) {
// Explicitly remove target for a proxy, if registered already,
// in order to avoid double invocations of the same listener.
Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
if (singletonTarget instanceof ApplicationListener) {
this.defaultRetriever.applicationListeners.remove(singletonTarget);
}
this.defaultRetriever.applicationListeners.add(listener);
// 检索缓存,是一个ConcurrentHashMap
this.retrieverCache.clear();
}
}
方法逻辑梳理如下:
- 如果listener是一个代理,则尝试获取其原始对象。如果获取到的原理对象为
ApplicationListener
则从defaultRetriever.applicationListeners
移除; - 否则放入
defaultRetriever.applicationListeners
。 - 清理retrieverCache
defaultRetriever
是ListenerRetriever
类型,内部维护了applicationListeners
集合。本文这里的defaultRetriever
是AbstractApplicationEventMulticaster
的成员。
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
private class ListenerRetriever {
//记录监听器实例
public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
// 记录监听器名称
public final Set<String> applicationListenerBeans = new LinkedHashSet<>();
private final boolean preFiltered;
//...
}
getSingletonTarget
getSingletonTarget是获取代理对象后面的单例目标对象()原始对象。如下所示如果是Advised且存在SingletonTargetSource类型的targetSource 则返回targetSource的target对象。否则返回null。
public static Object getSingletonTarget(Object candidate) {
if (candidate instanceof Advised) {
TargetSource targetSource = ((Advised) candidate).getTargetSource();
if (targetSource instanceof SingletonTargetSource) {
return ((SingletonTargetSource) targetSource).getTarget();
}
}
return null;
}
applicationListeners本文这里有17个监听器(记录的是AbstractApplicationContext的成员):
0 = {ConditionEvaluationReportLoggingListener$ConditionEvaluationReportListener@3203}
1 = {RSocketPortInfoApplicationContextInitializer$Listener@6339}
2 = {ServerPortInfoApplicationContextInitializer@6340}
3 = {RestartApplicationListener@6341}
4 = {CloudFoundryVcapEnvironmentPostProcessor@6342}
5 = {ConfigFileApplicationListener@6343}
6 = {AnsiOutputApplicationListener@6344}
7 = {LoggingApplicationListener@6345}
8 = {BackgroundPreinitializer@6346}
9 = {ClasspathLoggingApplicationListener@6347}
10 = {DelegatingApplicationListener@6348}
11 = {ParentContextCloserApplicationListener@6349}
12 = {DevToolsLogFactory$Listener@6350}
13 = {ClearCachesApplicationListener@3672}
14 = {FileEncodingApplicationListener@3695}
15 = {LiquibaseServiceLocatorApplicationListener@6351}
16 = {SharedMetadataReaderFactoryContextInitializer$SharedMetadataReaderFactoryBean@6352}
applicationListenerBeans有如下11个(记录的是容器中的):
0 = "&org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory"
1 = "cachingModelPropertiesProvider"
2 = "objectMapperBeanPropertyNamingStrategy"
3 = "optimized"
4 = "delegatingApplicationListener"
5 = "mvcResourceUrlProvider"
6 = "org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker"
7 = "springApplicationAdminRegistrar"
8 = "restartingClassPathChangedEventListener"
9 = "conditionEvaluationDeltaLoggingListener"
10 = "liveReloadServerEventListener"