前言
本文是作者写关于Spring源码的第一篇文章,作者水平有限,所有的源码文章仅限用作个人学习记录。文中如有错误欢迎各位留言指正。
resolveDefaultEventType
传入的参数类型new ApplicationStartingEvent(bootstrapContext, this.application, this.args)
。
继承结构及其构造方法。
java
private ResolvableType resolveDefaultEventType(ApplicationEvent event) {
return ResolvableType.forInstance(event);
}
实例方法resolveDefaultEventType调用了本身的静态方法forInstance,传入的参数就是透传事件类型实例对象。
java
public static ResolvableType forInstance(Object instance) {
Assert.notNull(instance, "Instance must not be null");
// 判断是不是这个类型 根据上面的时间类型的结构发现不是
if (instance instanceof ResolvableTypeProvider) {
ResolvableType type = ((ResolvableTypeProvider) instance).getResolvableType();
if (type != null) {
return type;
}
}
// 传入了事件实例对象的类型Class
return ResolvableType.forClass(instance.getClass());
}
接着调用静态方法forClass。参数换成了事件对象的类型Class实例。
操作很简单直接new了一个ResolvableType对象。
java
public static ResolvableType forClass(@Nullable Class<?> clazz) {
return new ResolvableType(clazz);
}
看看这个构造函数做了什么。
java
private ResolvableType(@Nullable Class<?> clazz) {
// clazz不为空,将事件类型的Class对象赋值给成员变量resolved
this.resolved = (clazz != null ? clazz : Object.class);
// 下面有Class的继承关系图一 Class 实现了Type接口
// 将事件类型的Class对象赋值给成员变量type
this.type = this.resolved;
this.typeProvider = null;
this.variableResolver = null;
this.componentType = null;
this.hash = null;
}
- 图一
只给resolved和type进行了赋值。
getApplicationListeners
java
protected Collection<ApplicationListener<?>> getApplicationListeners(
ApplicationEvent event, ResolvableType eventType) {
// 根据事件构造函数的跟进发现这个source是SpringApplication的实例对象
Object source = event.getSource();
// 这里就是SpringApplication的Class对象
Class<?> sourceType = (source != null ? source.getClass() : null);
// 组装一个key
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
// Potential new retriever to populate
CachedListenerRetriever newRetriever = null;
// Quick check for existing entry on ConcurrentHashMap
// 想从缓存中获取Listener
CachedListenerRetriever existingRetriever = this.retrieverCache.get(cacheKey);
// 缓存不存在
if (existingRetriever == null) {
// Caching a new ListenerRetriever if possible
if (this.beanClassLoader == null ||
(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
newRetriever = new CachedListenerRetriever();
existingRetriever = this.retrieverCache.putIfAbsent(cacheKey, newRetriever);
if (existingRetriever != null) {
newRetriever = null; // no need to populate it in retrieveApplicationListeners
}
}
}
if (existingRetriever != null) {
Collection<ApplicationListener<?>> result = existingRetriever.getApplicationListeners();
if (result != null) {
return result;
}
// If result is null, the existing retriever is not fully populated yet by another thread.
// Proceed like caching wasn't possible for this current local attempt.
}
// 这个方法里面感觉有点类似于业务代码 就不看了 弯弯绕绕的
return retrieveApplicationListeners(eventType, sourceType, newRetriever);
}
multicastEvent
java
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
// 遍历支持这个事件的listener
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
// 调用listener
invokeListener(listener, event);
}
}
}
invokeListener
java
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
// 这是一个null
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
// 调用listener
doInvokeListener(listener, event);
}
}
doInvokeListener
调用的是listener的onAppicationEvent方法,传入了事件对象。这个事件对象中的source是SpringApplication的对象实例。可以根据不同阶段知道SpringApplication中能获取到什么来处理自己的业务。
java
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()) ||
(event instanceof PayloadApplicationEvent &&
matchesClassCastMessage(msg, ((PayloadApplicationEvent) event).getPayload().getClass()))) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception.
Log loggerToUse = this.lazyLogger;
if (loggerToUse == null) {
loggerToUse = LogFactory.getLog(getClass());
this.lazyLogger = loggerToUse;
}
if (loggerToUse.isTraceEnabled()) {
loggerToUse.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
至此我们已经看完了listener的是如何加载并初始化的。也了解了Spring的所谓listener的整个工作流程。
简单总结一下:
初始化listener
- 就是初始化了一个SpringApplicationRunListeners实例。这个实例中包含了一个EventPublishingRunListener实例。
- EventPublishingRunListener实例中有SpringApplication的实例、arg参数、SimpleApplicationEventMulticaster对象。
- SimpleApplicationEventMulticaster中有所有的ApplicationListener
至此我们已经拥有了所有的listener。
再看如何发送消息的流程
- 调用SpringApplicationRunListeners的方法,比如starting。它的方法里面再调用自己的doWithListeners方法。
- 遍历调用SpringApplicationRunListener,这里就只有EventPublishingRunListener。
- 执行对应SpringApplicationRunListener的方法。都以starting方法为例。
- 调用SimpleApplicationEventMulticaster的方法multicastEvent。并且构造了事件作为参数传递。
- 在调用SimpleApplicationEventMulticaster的方法multicastEvent的重构方法。参数是事件和对事件的解析。
- ulticastEvent这个方法里面获取支持处理对应时间的listener,然后遍历这些listener,调用listener的onApplicationEvent方法。
OK 今天先到这里吧。
See you next time :)