您好,登录后才能下订单哦!
本篇内容介绍了“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有什么作用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。