springboot源码分析系列文章
springboot启动流程源码之一(new SpringApplication(primarySources))
springboot启动流程源码分析(二)run(args)
本文将主要分析getRunListeners()方法,该方法主要获取并启动监听器
该类中有一个方法 getSpringFactoriesInstances()是不是很熟悉,在源码分析(一)中对此方法进行了解读,主要是用来获取指定类型的实例集合。
那么在这儿,SpringAoolicationRunListener主要是获取哪个实现类呢?
在spring.factories中可以看到,获取的是org.springframework.boot.context.event.EventPublishingRunListener类。说的再简单点,getRunListeners就是准备好了运行时监听器EventPublishingRunListener。
在实现类EventPublishingRunListener的构造方法中,构造了一个SimpleApplicationEventMulticaster对象,并将SpringApplication的listeners中的全部listener赋值到SimpleApplicationEventMulticaster对象的属性defaultRetriever(类型是ListenerRetriever)的applicationListeners集合中。
//获取到监听器之后,启动监听器。
listeners.starting();
再来看看listeners.starting()做了什么操作。
构建了一个ApplicationStartingEvent事件,并将其发布出去,其中调用了resolveDefaultEventType方法,该方法返回了一个封装了事件的默认类型(ApplicationStartingEvent)的ResolvableType对象。我们接着往下看,看看这个发布过程做了些什么。
遍历getApplicationListeners(event, type),然后对每个listener进行invokeListener(listener, event)
①那么getApplicationListeners(event, type)是获取什么呢?
/**
* Return a Collection of ApplicationListeners matching the given
* event type. Non-matching listeners get excluded early.
* @param event the event to be propagated. Allows for excluding
* non-matching listeners early, based on cached matching information.
* @param eventType the event type
* @return a Collection of ApplicationListeners
* @see org.springframework.context.ApplicationListener
*/
protected Collection<ApplicationListener<?>> getApplicationListeners(
ApplicationEvent event, ResolvableType eventType) {
Object source = event.getSource();
Class<?> sourceType = (source != null ? source.getClass() : null);
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
// Quick check for existing entry on ConcurrentHashMap...
ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
// 从map中获取,如果之前已经存在该key,则直接从map获取
if (retriever != null) {
return retriever.getApplicationListeners();
}
if (this.beanClassLoader == null ||
(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
// Fully synchronized building and caching of a ListenerRetriever
synchronized (this.retrievalMutex) {
retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
retriever = new ListenerRetriever(true);
// map中没有该key,则先获取所有的监听器
Collection<ApplicationListener<?>> listeners =
retrieveApplicationListeners(eventType, sourceType, retriever);
// 重新put到map中,下次可以直接从map中获取
this.retrieverCache.put(cacheKey, retriever);
return listeners;
}
}
else {
// No ListenerRetriever caching -> no synchronization necessary
return retrieveApplicationListeners(eventType, sourceType, null);
}
}
跟踪retrieveApplicationListeners()方法,查看如何获取监听器列表
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
ResolvableType eventType, Class<?> sourceType, ListenerRetriever retriever) {
LinkedList<ApplicationListener<?>> allListeners = new LinkedList<ApplicationListener<?>>();
Set<ApplicationListener<?>> listeners;
Set<String> listenerBeans;
synchronized (this.retrievalMutex) {
// 1.从defaultReviewer中获取监听器列表
listeners = new LinkedHashSet<ApplicationListener<?>>(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
}
for (ApplicationListener<?> listener : listeners) {
// 2.针对于该Event事件的监听器,放入allListeners
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListeners.add(listener);
}
allListeners.add(listener);
}
}
if (!listenerBeans.isEmpty()) {
BeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : listenerBeans) {
try {
Class<?> listenerType = beanFactory.getType(listenerBeanName);
if (listenerType == null || supportsEvent(listenerType, eventType)) {
ApplicationListener<?> listener =
beanFactory.getBean(listenerBeanName, ApplicationListener.class);
// 针对于该Event事件的监听器,并且不存在于allListeners中的,则放入allListeners
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListenerBeans.add(listenerBeanName);
}
allListeners.add(listener);
}
}
}
catch (NoSuchBeanDefinitionException ex) {
// Singleton listener instance (without backing bean definition) disappeared -
// probably in the middle of the destruction phase
}
}
}
AnnotationAwareOrderComparator.sort(allListeners);
return allListeners;
}
通过以上代码可确定,监听器列表是从defaultRetriever中获取的
②invokeListener()方法做了什么
其注释:使用给定的事件调用给定的监听器getApplicationListeners方法过滤出的监听器都会被调用,过滤出来的监听器包括LoggingApplicationListener,
BackgroundPreinitializer,
DelegatingApplicationListener,
LiquibaseServiceLocatorApplicationListener,
EnableEncryptablePropertiesBeanFactoryPostProcessor
五种类型的对象。这五个对象的onApplicationEvent都会被调用。那么这五个监听器的onApplicationEvent都做了些什么了,
LoggingApplicationListener:检测正在使用的日志系统,默认是logback,支持3种,优先级从高到低:logback > log4j > javalog。此时日志系统还没有初始化
BackgroundPreinitializer:另起一个线程实例化Initializer并调用其run方法,包括验证器、消息转换器等等
DelegatingApplicationListener:此时什么也没做
LiquibaseServiceLocatorApplicationListener:此时什么也没做
EnableEncryptablePropertiesBeanFactoryPostProcessor:此时仅仅打印了一句日志,其他什么也没做
关注公众号
每周会更新干货知识