1. 介绍监听器的组成部分
springboot的监听器都是通过ApplicationListener
实现的类完成对监听事件的处理的,看得出来,所有的监听事件都是ApplicationEvent
ApplicationEventMulticaster
就是管理这些监听器的多播器,里面用一个集合存储了所有的ApplicationListener
的实现类,可以实现增加一个监听器,删除一个监听器,和执行所有监听器中的处理监听事件的方法等等。
1.1 会产生事件的环节
1.starting:springboot启动的时候发出该事件
2.environmentPrepared:环境准备完成的时候发出该事件,说明环境的一些的属性加载成功
3.contextInitialized:表示spring的上下文准备完成
4.prepared:表示上下文准备完成但是bean还没有完成初始化
5.started:表示当前bean已经实例化完成,但是还没有调用ApplicationRunner
6.ready:表示ApplicationRunner已经调用完成
1.2 监听器的初始化
监听器的初始化也是调用getSpringFactoriesInstances
,具体步骤和Spring Boot2.0版本源码(二):Spring Boot初始化器中的初始化器的初始化过程是一样的:
1.通过"META-INF/spring.factories"文件,获得所有的重写了带有ApplicationContextInitializer的全路径名
2.将这些类实例化
3.对这些类排序
2. 监听器的触发
在SpringApplication
的run()
方法内,有一行关于listeners.starting()
触发监听事件步骤。
跟进源码
继续跟进,发现其是调用了springboot的广播器实现对监听事件的调用
跟进multicastEvent(ApplicationEvent event)
方法
1.multicastEvent
里面调用了一个同名方法
2.通过getApplicationListeners(event, type)
获取对该event感兴趣的事件
3.执行第2步获取的所有的listener
2.2 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) {
// 事件的来源就是SpringbootApplication对象
Object source = event.getSource();
Class<?> sourceType = (source != null ? source.getClass() : null);
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
// Quick check for existing entry on ConcurrentHashMap...
// 从缓冲区中获取event事件感兴趣的监听者
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)))) {
// 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);
// retrieveApplicationListeners()方法实现获取eventType事件的监听事件
Collection<ApplicationListener<?>> listeners =
retrieveApplicationListeners(eventType, sourceType, retriever);
// 监听事件放入缓存
this.retrieverCache.put(cacheKey, retriever);
return listeners;
}
}
else {
// No ListenerRetriever caching -> no synchronization necessary
return retrieveApplicationListeners(eventType, sourceType, null);
}
}
跟进核心源码部分:retrieveApplicationListeners()
如何获取eventType事件的监听事件
1.遍历所有监听器,通过supportsEvent(listener, eventType, sourceType)
方法判断事件和监听器是否关联,将当前事件的关联的监听器全部加入list
2.对list排序
/**
* Actually retrieve the application listeners for the given event and source type.
* @param eventType the event type
* @param sourceType the event source type
* @param retriever the ListenerRetriever, if supposed to populate one (for caching purposes)
* @return the pre-filtered list of application listeners for the given event and source type
*/
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) {
listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
}
// Add programmatically registered listeners, including ones coming
// from ApplicationListenerDetector (singleton beans and inner beans).
// 遍历所有的监听器,然后
for (ApplicationListener<?> listener : listeners) {
// 判断当前监听器是否对listener对event感兴趣
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListeners.add(listener);
}
// 感兴趣的监听器会被加入到allListeners集合中
allListeners.add(listener);
}
}
// Add listeners by bean name, potentially overlapping with programmatically
// registered listeners above - but here potentially with additional metadata.
// listenerBeans默认为空,此处不做解释
if (!listenerBeans.isEmpty()) {
ConfigurableBeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : listenerBeans) {
try {
if (supportsEvent(beanFactory, listenerBeanName, eventType)) {
ApplicationListener<?> listener =
beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
if (beanFactory.isSingleton(listenerBeanName)) {
retriever.applicationListeners.add(listener);
}
else {
retriever.applicationListenerBeans.add(listenerBeanName);
}
}
allListeners.add(listener);
}
}
else {
// Remove non-matching listeners that originally came from
// ApplicationListenerDetector, possibly ruled out by additional
// BeanDefinition metadata (e.g. factory method generics) above.
Object listener = beanFactory.getSingleton(listenerBeanName);
if (retriever != null) {
retriever.applicationListeners.remove(listener);
}
allListeners.remove(listener);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Singleton listener instance (without backing bean definition) disappeared -
// probably in the middle of the destruction phase
}
}
}
// 所有监听器进行排序
AnnotationAwareOrderComparator.sort(allListeners);
if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
retriever.applicationListeners.clear();
retriever.applicationListeners.addAll(allListeners);
}
return allListeners;
}
继续跟进:supportsEvent(listener, eventType, sourceType)
的源码
1.GenericApplicationListenerAdapter
初始化的时候会完成对感兴趣的事件的解析,所以将所有的监听器封装成GenericApplicationListenerAdapter
类
2.利用supportsEventType()
来判断是否对该事件感兴趣,利用supportsSourceType()
来判断是否支持该事件的来源
/**
* Determine whether the given listener supports the given event.
* <p>The default implementation detects the {@link SmartApplicationListener}
* and {@link GenericApplicationListener} interfaces. In case of a standard
* {@link ApplicationListener}, a {@link GenericApplicationListenerAdapter}
* will be used to introspect the generically declared type of the target listener.
* @param listener the target listener to check
* @param eventType the event type to check against
* @param sourceType the source type to check against
* @return whether the given listener should be included in the candidates
* for the given event type
*/
protected boolean supportsEvent(
ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
// 将当前监听器封装成一个GenericApplicationListener
// GenericApplicationListenerAdapter初始化的时候会完成对感兴趣的事件的解析
GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
//supportsEventType()来判断是否对该事件感兴趣
// supportsSourceType()来判断是否支持该事件的来源
return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}
2.2.1 GenericApplicationListenerAdapter()
的构造函数
/**
* Create a new GenericApplicationListener for the given delegate.
* @param delegate the delegate listener to be invoked
*/
@SuppressWarnings("unchecked")
public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) {
Assert.notNull(delegate, "Delegate listener must not be null");
// 监听器
this.delegate = (ApplicationListener<ApplicationEvent>) delegate;
// 计算出感兴趣的事件
this.declaredEventType = resolveDeclaredEventType(this.delegate);
}
2.2.2 smartListener.supportsEventType(eventType)
源码
1.如果当前监听器是SmartApplicationListener
就调用其自身supportsEventType
方法判断其是否支持该事件
2.否则判断当前监听器的感兴趣事件和当前的evnetType是否相同
@Override
@SuppressWarnings("unchecked")
public boolean supportsEventType(ResolvableType eventType) {
// 如果是SmartApplicationListener就调用其自身supportsEventType方法判断其是否支持该事件
if (this.delegate instanceof SmartApplicationListener) {
Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass));
}
else {
// 判断当前监听器的感兴趣事件和当前的evnetType是否相同
return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
}
}
2.2.3 smartListener.supportsSourceType(sourceType))
判断事件的来源
1.判断当前监听器不是SmartApplicationListener返回true
2.当前监听器是SmartApplicationListener就调用supportsSourceType方法判断支持该事件的来源
@Override
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
// 如果当前监听器件不是SmartApplicationListener返回true
// 如果当前监听器是SmartApplicationListener就调用supportsSourceType方法判断支持该事件的来源
// 说明:实现SmartApplicationListener接口的listener感兴趣的事件都是一个ApplicationEvent这样一个大的监听事件
// 其他listener感兴趣的事件都会被详细指定
return !(this.delegate instanceof SmartApplicationListener) ||
((SmartApplicationListener) this.delegate).supportsSourceType(sourceType);
}
总结
获取event事件对应的监听器列表
supportsEvent的逻辑