通过前期的学习,我们发现在onRefresh方法之前的操作都是准备工作。在onRefresh方法之前的准备工作中,目前就剩下initApplicationEventMulticaster方法了。因为通过invokeBeanFactoryPostProcessors方法之后,所有需要的类均已经注册到beanDefinitionMap中,所以这块也应该是从beanDefinitionMap中获取特定接口的类并进行相关的操作。
从字面意思看,initApplicationEventMulticaster方法就是初始化一些广播器。通过之前的分析。在onRefresh方法之前的都是对beanFactory工厂的一些辅助。那么这里的init也应该是初始化beanFactory中的广播器。那么怎么初始化?那么应该和之前的beanPostProcessors是一样的,都需要通过beanDefinitionMap解析再获取实例化bean然后进行注册。
既然如此猜想,那就让我们走进看看吧!
代码语言:javascript复制 protected void initApplicationEventMulticaster() {
//获取beanFactory工厂
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//是否已经存在
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
//如果存在的话就拿到赋值
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" this.applicationEventMulticaster "]");
}
}
else {
//新创建一个,然后注册到beanFactory中
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" APPLICATION_EVENT_MULTICASTER_BEAN_NAME "' bean, using "
"[" this.applicationEventMulticaster.getClass().getSimpleName() "]");
}
}
}
我们看到这里也是直接创建一个SimpleApplicationEventMulticaster然后直接扔进IOC容器中并自己保留一份。
那么我们看看这里的SimpleApplicationEventMulticaster是何方神圣。
看到这里有线程工具和ErrorHandler,除此之外,还有很多方法比如doInvoke等。显然这里的类具有的作用就是执行。上边只是注册这个bean,那么后边肯定会有执行。那么这里的执行都是怎么执行的,还有他执行的条件是什么。
代码语言:javascript复制 @Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
//获取所有的监听器
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
//拿到线程池执
Executor executor = getTaskExecutor();
if (executor != null) {
//广播实践
executor.execute(() -> invokeListener(listener, event));
}
else {
//广播
invokeListener(listener, event);
}
}
}
//获取application类的实体
protected Collection<ApplicationListener<?>> getApplicationListeners(
ApplicationEvent event, ResolvableType eventType) {
Object source = event.getSource();
Class<?> sourceType = (source != null ? source.getClass() : null);
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
//从initApplicationEventMulticaster注册的retrieverMux中获取
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)))) {
// 加锁,retrievalMutex是beanFactory中的单例bean缓存。显然这块也是在onRefresh之后执行的
synchronized (this.retrievalMutex) {
retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
//拿到需要的Listner
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);
}
}
通过跟踪,发现这里的监听器的添加是在onrefresh之后的reginsterlistners方法中。
代码语言:javascript复制 //注册监听器
protected void registerListeners() {
// 获取监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
//从beanfactories中获取监听器
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
//添加到content中的属性中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
//拿到earlyApplicationEvents
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
//广播消息
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
通过上述分析,initApplicationEventMulticaster其实只是做了简单的初始化。并没有相关的功能实现。具体的广播事件其实是在IOC启动中调度的。注意这里是ApplicationListener接口的类。也就是这里获取都是实现了ApplicationListener接口的类。也就是说如果我们实现了ApplicationListener接口,然后调用multicastEvent方法就可以将我们的事件广播出去。但是这里multicastEvent谁可以调?我们看一下content的继承关系图谱。
发现有一个ApplicationEventPublisher,这是一个事件发布器。其中两个方法均为发布事件的。
我们看一下它的实现类。发现这里是有调用的。也就是说只要拿到了content,就可以将消息发布出去进行广播。
总结:在initApplicationEventMulticaster方法中,spring其实就是只是初始化了一个广播的中间类并放到ioc中并在自己哪里留存引用。真正向其中添加广播监听器是在onRefresh之后的registerListeners方法。而真正触发multicastEvent的方式是在content中调用publishEvent方法。