接下来看一下 initApplicationEventMulticaster
方法。
// 初始化事件监听多路广播器
initApplicationEventMulticaster();
监听器运用的其实就是观察者模式,不过spring中的监听器和常规的观察者模式有些不同。我们可以先看看一个常规的观察者模式是如何实现的。 这里贴一下Java与模式一书中对观察者模式的说明:
spring中监听器是基于事件驱动的:
- 逻辑执行过程
- 事件源来发布不同的事件
- 当发布事件之后会调用多播器的方法来进行事件广播操作,由多播器去触发具体的监听器去执行操作
- 监听器接收到具体的事件之后,可以验证匹配是否能处理当前事件,如果可以,直接处理,如果不行,不做任何操作
- 实际代码处理
- 提前准备好N多个事件
- 初始化多播器(创建多播器对象,此多播器对象中应该包含一个监听器的集合)
- 准备好一系列的监听器
- 向多播器中注册进去已有的监听器
- 准备事件发布,来通知多播器循环调用监听器进行相关的逻辑处理工作
接下来看看实际的代码:
- spring中的事件类
ApplicationEvent
- 初始化多播器
SimpleApplicationEventMulticaster
protected void initApplicationEventMulticaster() {
// 获取当前bean工厂,一般是DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判断容器中是否存在bdName为applicationEventMulticaster的bd,也就是说自定义的事件监听多路广播器,必须实现ApplicationEventMulticaster接口
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
// 如果有,则从bean工厂得到这个bean对象
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
// 如果没有,则默认采用SimpleApplicationEventMulticaster
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() + "]");
}
}
}
多播器中的监听器集合在父类 AbstractApplicationEventMulticaster
的内部类中:
- spring中的监听器对象
- 向多播器中注册进去已有的监听器
// Check for listener beans and register them.
// 在所有注册的bean中查找listener bean,注册到消息广播器中
registerListeners();
/**
* 注册监听器
*
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*/
protected void registerListeners() {
// Register statically specified listeners first.
// 遍历应用程序中存在的监听器集合,并将对应的监听器添加到监听器的多路广播器中
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...
// 此处先发布早期的监听器集合
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
- 准备事件发布,来通知多播器循环调用监听器进行相关的逻辑处理工作
在完成刷新的时候会调用
publishEvent
发布最终事件
/**
* 完成刷新
* Finish the refresh of this context, invoking the LifecycleProcessor's
* onRefresh() method and publishing the
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
// 清除上下文级别的资源缓存(如扫描的ASM元数据)
// 清空在资源加载器中的所有资源缓存
clearResourceCaches();
// Initialize lifecycle processor for this context.
// 为这个上下文初始化生命周期处理器
// 初始化LifecycleProcessor.如果上下文中找到'lifecycleProcessor'的LifecycleProcessor Bean对象,
// 则使用DefaultLifecycleProcessor
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
// 首先将刷新传播到生命周期处理器
// 上下文刷新的通知,例如自动启动的组件
getLifecycleProcessor().onRefresh();
// Publish the final event.
// 发布最终事件
// 新建ContextRefreshedEvent事件对象,将其发布到所有监听器。
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
// 参与LiveBeansView MBean,如果是活动的
// LiveBeansView:Sping用于支持JMX 服务的类
// 注册当前上下文到LiveBeansView,以支持JMX服务
LiveBeansView.registerApplicationContext(this);
}
在publishEvent
方法调用过程中会调用 multicastEvent 多播applicationEvent到适当的监听器
// 多播applicationEvent到适当的监听器
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
最终在 doInvokeListener
方法中会调用 listener.onApplicationEvent(event);
/**
* 回调listener的onApplicationEvent方法,传入 event
* @param listener
* @param event
*/
@SuppressWarnings({"rawtypes", "unchecked"})
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
//回调listener的onApplicationEvent方法,传入event:contextrefreshListener:onapplicaitonEvent:FrameworkServlet.this.onApplicationEvent()
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
//获取异常信息
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
//抛出异常
throw ex;
}
}
}