springboot 源码(二)监听器 ApplicationListener
muticaster(广播器) —发布—> eventA(事件) —监听—> listenerA(监听器)
事件
监听器
广播器
触发机制
ApplicationListener
ApplicationEventMulticaster
EventObject——|
|——ApplicationEvent
|——SpringApplicationEvent
|——ApplicationContextIntializedEvent
|——ApplicationEnvironmentPreparedEvent
|——ApplicationFaildEvent
|——ApplicationPreparedEvent
|——ApplicationReadyEvent
|——ApplicationStartedEvent
|——ApplicationStartingEvent
spring 框架发送顺序
|启动失败——>failed
|
框架启动——>starting——>enviromentPrepared——> ContextIntialized——>Prepared ——>started——> ready——>启 动完毕
SpringApplication
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 配置初始化器
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 配置监听器,可以看见科构造初始化器是一样的,所以使用步骤也一样的,可以参阅 系列文章 https://blog.csdn.net/weixin_37765815/article/details/123865470
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
springboot 启动 调用 EventPublishingRunListener的 starting() 方法
SpringApplicationRunListener
EventPublishingRunListener
@Override
public void starting() {
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}
SimpleApplicationEventMulticaster
@Override
// ResolvableType 获取时间的类型
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);
}
}
}
AbstractApplicationEventMulticaster
protected Collection<ApplicationListener<?>> getApplicationListeners(
ApplicationEvent event, ResolvableType eventType) {
// source 就是 springAplication 对象 ,从事件对象中获取
Object source = event.getSource();
Class<?> sourceType = (source != null ? source.getClass() : null);
// 获取缓存key ,计算这个事件哪些监听器感兴趣,计算完了之后会放到缓存中,下次直接获取
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
// Quick check for existing entry on ConcurrentHashMap...
// 获取从索引中拿到的监听器
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
// 上个同步锁
c {
// 注意点1:锁内再次获取,this.retrievalMutex 是属性锁,不同实例可以进行同步执行。
// 注意点2: 双重检查,线程1 获得锁,放入缓存,线程2 已经执行到 synchronized (this.retrievalMutex) 等待锁,线程2进入后,没必要再放一遍缓存,所以还需要判断下缓存是不是已经赋值了
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 {
// No ListenerRetriever caching -> no synchronization necessary
// 没有缓存,并且没有同步执行的必要
return retrieveApplicationListeners(eventType, sourceType, null);
}
}
遍历监听器
AbstractApplicationEventMulticaster
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) {
// 看哪些监听器对这个事件感兴趣
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListeners.add(listener);
}
allListeners.add(listener);
}
}
// Add listeners by bean name, potentially overlapping with programmatically
// registered listeners above - but here potentially with additional metadata.
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;
}
ConfigFileApplicationListener 不是GenericApplicationListener 的子类
AbstractApplicationEventMulticaster
protected boolean supportsEvent(
ApplicationListener> listener, ResolvableType eventType, @Nullable Class> sourceType) {
// 通过上图所示,会进入到 new GenericApplicationListenerAdapter(listener))
GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}
监听器适配器
GenericApplicationListenerAdapter
public GenericApplicationListenerAdapter(ApplicationListener> delegate) {
Assert.notNull(delegate, "Delegate listener must not be null");
this.delegate = (ApplicationListener) delegate;
this.declaredEventType = resolveDeclaredEventType(this.delegate);
}
// 这个方法目的是获取下图中泛型的类型
@Nullable
private static ResolvableType resolveDeclaredEventType(ApplicationListener 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;
}
@Override
@SuppressWarnings("unchecked")
public boolean supportsEventType(ResolvableType eventType) {
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));
}
}
public class SecondListener implements SmartApplicationListener {
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return ApplicationStartedEvent.class.isAssignableFrom(eventType);
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("ll");
}
}