SpringBoot启动分析2:SpringApplicationRunListeners初始化
当SpringApplication初始化完毕后,就开始调用实际的run方法执行其他初始化了。
本地分析SpringApplicationRunListeners的初始化过程,源码如下:
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
1.1 初始化EventPublishingRunListener
EventPublishingRunListener是SpringApplicationRunListener的实现,是实际用于发布SpringApplicationEvent类型的事件的实现类。点击getRunListeners跟进源码:
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
依然是调用通用的方法getSpringFactoriesInstances根据对应的类型来读取spring.factories中的实现:
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener
需要注意的是除了类型参数(SpringApplicationRunListener),还包含已经初始化好的SpringApplication和String类。SpringApplication参数是为了获取内部已通过spring.factories中读取的Listener。
从之前的getSpringFactoriesInstances方法可知读取到对应的EventPublishingRunListener实现后会对该实现类进行实例化,以下跟进EventPublishingRunListener的构造方法:
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
private final SpringApplication application;
private final String[] args;
private final SimpleApplicationEventMulticaster initialMulticaster;
public EventPublishingRunListener(SpringApplication application, String[] args) {
this.application = application;
this.args = args;
// 对initialMulticaster进行实例化
this.initialMulticaster = new SimpleApplicationEventMulticaster();
// SpringApplication参数的作用体现出来了,用于遍历listeners
for (ApplicationListener<?> listener : application.getListeners()) {
this.initialMulticaster.addApplicationListener(listener);
}
}
}
这里将initialMulticaster变量进行初始化实例,最终通过该实例调用其抽象类AbstractApplicationEventMulticaster的addApplicationListener方法将SpringApplication初始化时的Listeners一个个加入到其中,点击addApplicationListener跟进源码:
public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
final Map<ListenerCacheKey, ListenerRetriever> retrieverCache = new ConcurrentHashMap<>(64);
private Object retrievalMutex = this.defaultRetriever;
@Override
public void addApplicationListener(ApplicationListener<?> listener) {
synchronized (this.retrievalMutex) {
Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
if (singletonTarget instanceof ApplicationListener) {
this.defaultRetriever.applicationListeners.remove(singletonTarget);
}
this.defaultRetriever.applicationListeners.add(listener);
this.retrieverCache.clear();
}
}
}
private class ListenerRetriever {
public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
......
}
在ListenerRetriever中维护着一个Set集合,该Set集合存放着从SpringApplication中获取到的listeners集合,它的作用在于后续遍历监听器,判断监听器是否支持某个事件提供了数据源。
1.2 筛选支持指定事件的Listener
当EventPublishingRunListener初始化完成后,调用其starting方法开始根据指定的事件遍历Listener是否支持该指定事件:
class SpringApplicationRunListeners {
void starting() {
for (SpringApplicationRunListener listener : this.listeners) {
listener.starting();
}
}
}
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
@Override
public void starting() {
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}
}
可以看出该指定事件为ApplicationStartingEvent,需要注意的是本次判断一个listener是否支持某个事件指的就是ApplicationStartingEvent。
点击multicastEvent跟进源码,这里主要将对应的事件包装成ResolvableType类型,遍历listeners,对于支持ApplicationStartingEvent事件的listener调用其内部的onApplicationEvent方法:
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
@Override
public void multicastEvent(ApplicationEvent event) {
// 这里将event包装成ResolvableType
multicastEvent(event, resolveDefaultEventType(event));
}
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
// 获取对事件支持的监听器,不支持的不会出现在一下的循环体内
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
}
获取对事件支持的监听器,核心方法在于getApplicationListeners,这里遍历了Listeners,判断每个Listener是否支持指定的事件(即ApplicationStartingEvent),点击getApplicationListeners跟进源码:
public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
final Map<ListenerCacheKey, ListenerRetriever> retrieverCache = new ConcurrentHashMap<>(64);
@Nullable
private ClassLoader beanClassLoader;
private Object retrievalMutex = this.defaultRetriever;
protected Collection<ApplicationListener<?>> getApplicationListeners(ApplicationEvent event, ResolvableType eventType) {
Object source = event.getSource();
Class<?> sourceType = (source != null ? source.getClass() : null);
// 将事件类型和启动类作为参数包装成一个ListenerCacheKey作为缓存key
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
// 从缓存获取支持事件的监听器,由于之前没有初始化过retrieverCache所以这里并获取不到
ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
if (this.beanClassLoader == null ||
(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
synchronized (this.retrievalMutex) {
retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
retriever = new ListenerRetriever(true);
// 实际获取支持事件的监听器列表
Collection<ApplicationListener<?>> listeners =
retrieveApplicationListeners(eventType, sourceType, retriever);
this.retrieverCache.put(cacheKey, retriever);
return listeners;
}
}
else {
return retrieveApplicationListeners(eventType, sourceType, null);
}
}
}
启动时的初始化是不存在缓存的,所以进入retrieveApplicationListeners方法跟进源码:
public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
final Map<ListenerCacheKey, ListenerRetriever> retrieverCache = new ConcurrentHashMap<>(64);
private Object retrievalMutex = this.defaultRetriever;
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {
List<ApplicationListener<?>> allListeners = new ArrayList<>();
Set<ApplicationListener<?>> listeners;
Set<String> listenerBeans;
synchronized (this.retrievalMutex) {
// defaultRetriever就是初始化EventPublishingRunListener时调用父类AbstractApplicationEventMulticaster的addApplicationListener方法对其进行初始化
listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
}
// 遍历每个监听器,之前说的ListenerRetriever中维护着一个Set集合就是为此提供了数据源
for (ApplicationListener<?> listener : listeners) {
// 实际判断监听器是否支持事件的方法
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListeners.add(listener);
}
allListeners.add(listener);
}
}
...... // 省略
// 对监听器进行排序,为了监听器的执行顺序
AnnotationAwareOrderComparator.sort(allListeners);
if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
retriever.applicationListeners.clear();
retriever.applicationListeners.addAll(allListeners);
}
return allListeners;
}
}
最终判断监听器是否支持某种事件类型是通过supportsEvent方法来进行,点击supportsEvent跟进源码:
public abstract class AbstractApplicationEventMulticasterimplements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
protected boolean supportsEvent(
ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
// 判断listener是否属于GenericApplicationListener类型转换不同的适配,用于根据不同适配调用对应的用于判断是否支持某个事件类型的supportsEventType方法
GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}
}
这里分为以下两种情况:
- 若属于GenericApplicationListener的子类则通过GenericApplicationListener父类调用自身的supportsEventType方法判断自己是否支持此事件
- 若不属于GenericApplicationListener的子类则通过GenericApplicationListenerAdapter统一判断listener是否支持此事件
1.2.1 情况一:属于GenericApplicationListener的子类
以LoggingApplicationListener为例,它是属于GenericApplicationListener的子类,类简要定义如下:
public class LoggingApplicationListener implements GenericApplicationListener {
private static final Class<?>[] EVENT_TYPES = {
ApplicationStartingEvent.class
, ApplicationEnvironmentPreparedEvent.class
, ApplicationPreparedEvent.class
, ContextClosedEvent.class
, ApplicationFailedEvent.class };
private static final Class<?>[] SOURCE_TYPES = { SpringApplication.class, ApplicationContext.class };
@Override
public boolean supportsEventType(ResolvableType resolvableType) {
// 通过父类调用本身的supportsEventType方法校验支持的事件
return isAssignableFrom(resolvableType.getRawClass(), EVENT_TYPES);
}
// 最终的校验方法
private boolean isAssignableFrom(Class<?> type, Class<?>... supportedTypes) {
if (type != null) {
for (Class<?> supportedType : supportedTypes) {
if (supportedType.isAssignableFrom(type)) {
return true;
}
}
}
return false;
}
}
从常量EVENT_TYPES定义的该listener支持的事件类型就可以判断出它是支持ApplicationStartingEvent事件。
1.2.2 情况二:不属于GenericApplicationListener的子类
不属于GenericApplicationListener的子类则是实例化出new GenericApplicationListenerAdapter(listener)),进入GenericApplicationListenerAdapter构造:
public class GenericApplicationListenerAdapter implements GenericApplicationListener, SmartApplicationListener {
private final ApplicationListener<ApplicationEvent> delegate;
@Nullable
private final ResolvableType declaredEventType;
public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) {
Assert.notNull(delegate, "Delegate listener must not be null");
this.delegate = (ApplicationListener<ApplicationEvent>) delegate;
// 这里解析出listener的实际泛型事件并包装成ResolvableType,待后续通过该adapter调用其supportsEventType判断是否支持时间时有用
this.declaredEventType = resolveDeclaredEventType(this.delegate);
}
@Nullable
private static ResolvableType resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener) {
ResolvableType declaredEventType = resolveDeclaredEventType(listener.getClass());
if (declaredEventType == null || declaredEventType.isAssignableFrom(ApplicationEvent.class)) {
Class<?> targetClass = AopUtils.getTargetClass(listener);
if (targetClass != listener.getClass()) {
declaredEventType = resolveDeclaredEventType(targetClass);
}
}
return declaredEventType;
}
@Nullable
static ResolvableType resolveDeclaredEventType(Class<?> listenerType) {
ResolvableType eventType = eventTypeCache.get(listenerType);
if (eventType == null) {
eventType = ResolvableType.forClass(listenerType).as(ApplicationListener.class).getGeneric();
eventTypeCache.put(listenerType, eventType);
}
return (eventType != ResolvableType.NONE ? eventType : null);
}
}
可以看出这种方式就是对于每个不属于GenericApplicationListener子类的listener都创建一个GenericApplicationListenerAdapter对象,根据listener获取其支持的事件并对内部属性进行初始化;
后续调用GenericApplicationListenerAdapter对象的supportsEventType方法判断是否支持某个事件时GenericApplicationListenerAdapter对象就能获取到该listener已解析过的支持的事件类型:
public class GenericApplicationListenerAdapter implements GenericApplicationListener, SmartApplicationListener {
@Override
@SuppressWarnings("unchecked")
public boolean supportsEventType(ResolvableType eventType) {
// 根据是否是属于SmartApplicationListener类型的实例执行不同的判断
if (this.delegate instanceof SmartApplicationListener) {
Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass));
}
else {
return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
}
}
}
可以看出这里又分为两种情况:
- listener属于SmartApplicationListener的子类
- listener不属于SmartApplicationListener的子类
不属于SmartApplicationListener子类
若listener非SmartApplicationListener子类则进入else方法,else方法体中的declaredEventType属性是在初始化GenericApplicationListenerAdapter时就被解析出了事件类型所包装的对象。
例如CloudFoundryVcapEnvironmentPostProcessor,它的定义如下:
public class CloudFoundryVcapEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered, ApplicationListener<ApplicationPreparedEvent> {}
所以以上的declaredEventType属性在CloudFoundryVcapEnvironmentPostProcessor被解析事件类型后解析出来的为ApplicationPreparedEvent事件,最终isAssignableFrom方法是这么判断该listener是否支持事件:
if (ourResolved == null) {
// listener支持的事件,CloudFoundryVcapEnvironmentPostProcessor支持ApplicationPreparedEvent事件
ourResolved = resolve(Object.class);
}
Class<?> otherResolved = other.toClass();
// otherResolved是实际需要支持的事件,这里初始化的事件为ApplicationStartingEvent
if (exactMatch ? !ourResolved.equals(otherResolved) : !ClassUtils.isAssignable(ourResolved, otherResolved)) {
return false;
}
所以CloudFoundryVcapEnvironmentPostProcessor并不支持ApplicationStartingEvent事件,所以本次初始化它的onApplicationEvent并不会得到执行。
属于SmartApplicationListener子类
若listener属于SmartApplicationListener子类则进入if方法,例如ConfigFileApplicationListener,它的简要类定义如下:
public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType)
|| ApplicationPreparedEvent.class.isAssignableFrom(eventType);
}
}
对于属于SmartApplicationListener的子类,则是将listener转换成父类,通过调用父类的supportsEventType方法达到调用自身supportsEventType方法来做判断,但是从ConfigFileApplicationListener的supportsEventType方法来看明细它是不支持ApplicationStartingEvent。
1.3 Listner排序并发布
对于上述筛选出来的listener,为了确保其执行顺序则对它进行排序:
AnnotationAwareOrderComparator.sort(allListeners);
这种排序已经看到在许多地方出现过,比如初始化SpringApplication的Initializers和Listeners,所以这里不再详细说明。
1.3.1 发布Listener
以下是筛选了支持指定事件的Listener:
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
}
由于executor为空,所以这里都是调用了else方法提内的invokeListener方法。
对于listener来说,每个listener都会实现ApplicationListener或者其子接口SmartApplicationListener,所以它们都会重写onApplicationEvent方法:
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
// 最终还是调用每个支持该事件的listener中的重写了父类的onApplicationEvent方法
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
}
1.3.2 发布Listener说明
贯穿整个SpringBoot的启动过程,会有多次类似上面获取监听器所支持的事件进行发布,区别在于不同的初始化流程传入的需要支持的事件类型不同, 以下是EventPublishingRunListener的源码:
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
@Override
public void starting() {
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
this.initialMulticaster.multicastEvent(new ApplicationContextInitializedEvent(this.application, this.args, context));
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
for (ApplicationListener<?> listener : this.application.getListeners()) {
if (listener instanceof ApplicationContextAware) {
((ApplicationContextAware) listener).setApplicationContext(context);
}
context.addApplicationListener(listener);
}
this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
}
@Override
public void started(ConfigurableApplicationContext context) {
context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));
}
@Override
public void running(ConfigurableApplicationContext context) {
context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context));
}
......
}