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));
	}

	......
}
原文地址:https://www.cnblogs.com/Json1208/p/13352751.html