们分析过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的成员。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"