Spring
源码 - 容器刷新#initApplicationEventMulticaster()
Spring
版本:Spring 5.3.13-release
# 1、initApplicationEventMulticaster()
初始化事件监听多路广播器
AbstractApplicationContext#initApplicationEventMulticaster()
代码:
/**
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
// 获取 BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 从容器中获取 BeanName 为 applicationEventMulticaster 的 Bean 实例(如果用户自定义了事件广播器, 则使用用户自定义的事件广播器)
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
// 如果存在则从容器中获取 BeanName 为 applicationEventMulticaster 类型为 ApplicationEventMulticaster 的 Bean 实例, 并将其赋值为容器内部的事件广播器
this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
// 如果容器中不存在 BeanName 为 applicationEventMulticaster 的 Bean 实例, 则 Spring 会使用
// SimpleApplicationEventMulticaster 作为当前容器内的默认事件广播器
else {
// 创建 SimpleApplicationEventMulticaster 事件广播器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
// 将其以 BeanName 为 applicationEventMulticaster 注册到 IOC 容器中
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() + "]");
}
}
}
从上面的代码可以看出,如果用户自定义了事件广播器,并且用户自定义的事件广播器的BeanName
为applicationEventMulticaster
,Spring则会使用用户自定义的事件广播器。
如果用户没有自定义事件广播器,或者用户自定义的事件广播器的BeanName
不为applicationEventMulticaster
,Spring
会使用默认的事件广播器SimpleApplicationEventMulticaster
。
SimpleApplicationEventMulticaster
中有一个multicastEvent
方法,当Spring
容器完成刷新事件的时候会调用这个方法:
@Override
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);
}
}
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
doInvokeListener(listener, event);
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass()) ||
(event instanceof PayloadApplicationEvent &&
matchesClassCastMessage(msg, ((PayloadApplicationEvent) event).getPayload().getClass()))) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception.
Log loggerToUse = this.lazyLogger;
if (loggerToUse == null) {
loggerToUse = LogFactory.getLog(getClass());
this.lazyLogger = loggerToUse;
}
if (loggerToUse.isTraceEnabled()) {
loggerToUse.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
从上面的代码可以看出,首先会遍历所有的监听器,如果获取的线程池不为空,则异步执行。最总由doInvokeListener()
方法中的listener.onApplicationEvent(event)
进行监听事件的处理。
GitHub源码地址:https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13
备注:此文为笔者学习
Spring
源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。