1. 准备
-
ApplicationEvent: 事件对象,Spring事件驱动模型中的对象源,继承JDK EventObject,通过在发布事件时通过EventObject.source字段携带事件相关的数据。
-
ApplicationListener: 应用监听器,负责监听事件对象是否有发生变化,实现该接口并实现onApplicationEvent方法,完成事件发生变化时的逻辑处理
-
ApplicationEventPublisher,事件发布器,定义了事件发布规范,只是接口,具体的实现交给
实现类。
-
ApplicationEventMulticaster,负责管理监听器,提供了增删监听者的方法。AbstractApplicationEventMulticaster类扩展了获取监听者的方法。
2. 源码
protected void registerListeners() {
// Register statically specified listeners first.
// 首先获取AbstractApplicationContext#applicationListeners属性集合,有的话就添加进去。 核心主要是prepareRefresh() 中earlyApplicationListeners是否为空
//此处获取的是abstractApplicationContext集合中的,添加到多播器中
//备注1
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 从容器中获取所有实现了ApplicationListener接口的bd的bdName
// 放入ApplicationListenerBeans集合中。我猜测是注解扫描到的,我们自定义的。
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
//可以改写为: getApplicationEventMulticaster().addApplicationListener(this.getBean(listenerBeanName,ApplicationListener.class));
}
// Publish early application events now that we finally have a multicaster...
// 已经初始化过一个多播器了,此处先发布早期的事件(如果有的话), prepare时候添加的
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
备注1: 如在springboot中,run() ->prepareContext(…)->applyInitializers(context)-> initialize(…) // 会有一些 addApplicationListener 操作,赋值给applicationListeners ,此处就不是空了。
3. 思考
3.1 逻辑执行过程
- 事件源发布不通的事件
- 当发布事件之后会调用多播器的方法进行事件的广播操作,由多播器去触发具体监听器去执行操作
- 当监听器接收到具体事件后,可以匹配验证是否处理当前事件。
3.2 代码处理过程
-
提起准备好多个事件
-
初始化多播器,多播器含有一个监听器的集合
initApplicationEventMulticaster();
-
准备好一系列的监听器
-
向多播器中注册进去已有的监听器
registerListeners()
-
准备事件发布,通知多播器循环调用监听器进行相关逻辑处理工作