本篇内容介绍了“Springboot中AbstractApplicationEventMulticaster有什么作用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
Springboot的版本2.0.9.release,对应的SpringFramework值5.0.x.release。
AbstractApplicationEventMulticaster并不是Springboot里面的,而是属于SpringFramework的。

图1
如上图1所示,AbstractApplicationEventMulticaster继承了BeanFactoryAware,用于获取BeanFactory;ApplicationEventMulticaster则包含增加、删除ApplicationListener的接口方法,支持对象和String类型的bean名称。
一开始以为AbstractApplicationEventMulticaster应该有个List<ApplicationListener>的属性用于存放加入其中的ApplicationListener,但是看了源码之后,发现Spring考虑的更周全、考虑的情况更多。
List-1
public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
private final AbstractApplicationEventMulticaster.ListenerRetriever defaultRetriever = new AbstractApplicationEventMulticaster.ListenerRetriever(false);
final Map<AbstractApplicationEventMulticaster.ListenerCacheKey, AbstractApplicationEventMulticaster.ListenerRetriever> retrieverCache = new ConcurrentHashMap(64);
@Nullable
private ClassLoader beanClassLoader;
@Nullable
private BeanFactory beanFactory;
private Object retrievalMutex;
...
private class ListenerRetriever {
public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet();
public final Set<String> applicationListenerBeans = new LinkedHashSet();
private final boolean preFiltered;
public ListenerRetriever(boolean preFiltered) {
this.preFiltered = preFiltered;
}
...
如上的List-1,ListenerRetriever中的LinkedHashSet,才是真正存放ApplicationListener的地方。而retrieverCache则是用于作为缓存,为什么要做缓存,是因为我们丢给AbstractApplicationEventMulticaster的Event不一定会被发送,只有找到能支持这种Event的ApplicationListener才会进行发送。
首先来看下addApplicationListener,如下List-2,如果是ApplicationListener的实例,则加入到defaultRetriever的Set中,如果是String类型的beanName,则加入到defaultRetriever的applicationListenerBeans中,最后都调用retrieverCache的clear方法,retrieverCache是个线程安全的Map,因为新加入了ApplicationListener,所以我们需要更新我们的缓存。
List-2
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();
}
}
public void addApplicationListenerBean(String listenerBeanName) {
synchronized(this.retrievalMutex) {
this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
this.retrieverCache.clear();
}
}
...
来看retrieveApplicationListeners方法的实现,这个很重要,因为发送Event之前,会先检索出支持这种event的ApplicationListener。如下所示List-3:
遍历applicationListeners,调用supportsEvent方法,如果支持,加将当前的ApplicationListener加入到结果集中。
之后遍历applicationListenerBeans,先从BeanFactory中获取对应的ApplicationListener实例,如果BeanFactory中含有对应的ApplicationListener,且supportsEvent方法返回true,那么将当前的ApplicationListener加入到结果集中。
最后调用AnnotationAwareOrderComparator进行排序。
List-3
private Collection<ApplicationListener<?>> retrieveApplicationListeners(ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable AbstractApplicationEventMulticaster.ListenerRetriever retriever) {
List<ApplicationListener<?>> allListeners = new ArrayList();
LinkedHashSet listeners;
LinkedHashSet listenerBeans;
synchronized(this.retrievalMutex) {
listeners = new LinkedHashSet(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet(this.defaultRetriever.applicationListenerBeans);
}
Iterator var7 = listeners.iterator();
while(var7.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var7.next();
if (this.supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListeners.add(listener);
}
allListeners.add(listener);
}
}
if (!listenerBeans.isEmpty()) {
BeanFactory beanFactory = this.getBeanFactory();
Iterator var15 = listenerBeans.iterator();
while(var15.hasNext()) {
String listenerBeanName = (String)var15.next();
try {
Class<?> listenerType = beanFactory.getType(listenerBeanName);
if (listenerType == null || this.supportsEvent(listenerType, eventType)) {
ApplicationListener<?> listener = (ApplicationListener)beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (!allListeners.contains(listener) && this.supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListenerBeans.add(listenerBeanName);
}
allListeners.add(listener);
}
}
} catch (NoSuchBeanDefinitionException var13) {
}
}
}
AnnotationAwareOrderComparator.sort(allListeners);
return allListeners;
}
AbstractApplicationEventMulticaster的子类,需要实现multicastEvent方法,我们来看下SimpleApplicationEventMulticaster是如何实现的。
如下List-4所示,默认情况下taskExecutor是null。
multicastEvent方法中调用父类的getApplicationListeners方法获取支持Event的ApplicationListener,之后遍历ApplicationListener,如果taskExecutor不是null,则交给Executor;否则逐个调用ApplicationListener的onApplicationEvent方法。
List-4
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
@Nullable
private Executor taskExecutor;
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
Iterator var4 = this.getApplicationListeners(event, type).iterator();
while(var4.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var4.next();
Executor executor = this.getTaskExecutor();
if (executor != null) {
executor.execute(() -> {
this.invokeListener(listener, event);
});
} else {
this.invokeListener(listener, event);
}
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
listener.onApplicationEvent(event);
} catch (ClassCastException var6) {
String msg = var6.getMessage();
if (msg != null && !this.matchesClassCastMessage(msg, event.getClass())) {
throw var6;
}
}
}
...
Springboot中SpringApplicationRunListener的默认实现有个EventPublishingRunListener,如下List-5所示
List-5
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
private final SimpleApplicationEventMulticaster initialMulticaster;
...
@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 started(ConfigurableApplicationContext context) {
context.publishEvent(
new ApplicationStartedEvent(this.application, this.args, context));
}
...
如List-5中所示,Springboot启动的不同阶段,会传不同的event实现给EventPublishingRunListener,而EventPublishingRunListener则用Delete委托模式,交给initialMulticaster去处理。当然,started、running、failed事件则交给ConfigurableApplicationContext去处理。
来看EventPublishingRunListener的构造方法如下List-6所示,从SpringApplication中获取Listener,之后加入到SimpleApplicationEventMulticaster中,所以Springboot中的事件是先交给SpringApplicationRunListener,之后SpringApplicationRunListener再委托给ApplicationListener的实现类完成具体的。
List-6
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
private final SpringApplication application;
private final SimpleApplicationEventMulticaster initialMulticaster;
...
public EventPublishingRunListener(SpringApplication application, String[] args) {
this.application = application;
this.args = args;
this.initialMulticaster = new SimpleApplicationEventMulticaster();
for (ApplicationListener<?> listener : application.getListeners()) {
this.initialMulticaster.addApplicationListener(listener);
}
}
...
ApplicationListener的实现类如下图2

图2
“Springboot中AbstractApplicationEventMulticaster有什么作用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注天达云网站,小编将为大家输出更多高质量的实用文章!