描述
在Spring之事件機(jī)制模型中我們了解了spring事件機(jī)制的模型以及工作流程,下面通過(guò)源碼分析spring事件機(jī)制的初始化流程
在工作流程中兜粘,可以看到事件發(fā)布者ApplicationEventPublisher 發(fā)布事件是通過(guò)事件廣播中心ApplicationEventMulticaster 將事件event通知到具體的事件監(jiān)聽(tīng)器ApplicationListener 那么初始化流程應(yīng)該有如下幾步:
- 給事件發(fā)布者ApplicationEventPublisher 設(shè)置ApplicationEventMulticaster并初始化
- 注冊(cè)事件監(jiān)聽(tīng)器到事件ApplicationEventMulticaster
- 事件發(fā)布時(shí)萍桌,通過(guò)ApplicationEventMulticaster通知事件監(jiān)聽(tīng)器柠掂。
初始化入口
// 類 AbstractApplicationContext
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//容器刷新前的處理方法
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//使用容器前beanFactory的前置處理方法
prepareBeanFactory(beanFactory)
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
//在容器中執(zhí)行bean工廠后置處理器
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
//初始化容器的事件廣播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// 注冊(cè)事件監(jiān)聽(tīng)器到事件廣播器中
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
}
catch (BeansException ex) {
throw ex;
}
}
}
ApplicaitonContext 繼承事件發(fā)布者接口熊杨,在ApplicaitonContext的refresh方法中完成了事件機(jī)制初始化的流程,如下:
- 初始化發(fā)布者即容器的事件廣播中心ApplicationEventMulticaster
//初始化容器的事件廣播器
initApplicationEventMulticaster();
- 注冊(cè)事件監(jiān)聽(tīng)器到事件廣播中心
// 注冊(cè)事件監(jiān)聽(tīng)器到事件廣播器中
registerListeners();
initApplicationEventMulticaster
/**
* 初始化當(dāng)前容器發(fā)布者持有的事件廣播中心實(shí)例
*/
protected void initApplicationEventMulticaster() {
//獲取beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判斷beanFactory中是否存在事件廣播中心bean實(shí)例
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
//存在時(shí)别垮,beanFactory中的事件廣播中心bean實(shí)例賦值給applicationEventMulticaster
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
}
else {
//不能存在挑胸,new 創(chuàng)建新的applicationEventMulticaster并賦值給applicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
//將創(chuàng)建的新事件廣播中心bean實(shí)例注冊(cè)到單例bean注冊(cè)中心
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}
initApplicationEventMulticaster 方法主要功能是創(chuàng)建事件廣播中心實(shí)例,創(chuàng)建的方式:
- beanFactory 已經(jīng)存在實(shí)例 宰闰,通過(guò)beanFactory獲取已經(jīng)存在的實(shí)例賦值給當(dāng)前發(fā)布者
- 不存在茬贵,通過(guò)new 關(guān)鍵字創(chuàng)建實(shí)例,賦值給發(fā)布者移袍,并將當(dāng)前實(shí)例注冊(cè)到單例注冊(cè)中心
registerListeners
protected void registerListeners() {
// 注冊(cè)靜態(tài)指定的事件監(jiān)聽(tīng)器ApplicationListener到事件廣播中心ApplicationEventMulticaster
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 在beanFactory中查找ApplicationListener名稱集合
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
//遍歷名稱并將當(dāng)前名稱的事件監(jiān)聽(tīng)器注冊(cè)到事件廣播中心
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
//所有事件監(jiān)聽(tīng)器添加完成后解藻,遍歷發(fā)布者(ApplicationEventPublisher-ApplicaitonContext)已經(jīng)發(fā)布的事件集合,并將事件通知到給定的監(jiān)聽(tīng)器
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
//通過(guò)事件廣播中心ApplicationEventMulticaster葡盗,下發(fā)事件到具體的監(jiān)聽(tīng)器ApplicationListener
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
registerListeners 方法主要完成將監(jiān)聽(tīng)器注冊(cè)到事件廣播中心實(shí)例中螟左,在initApplicationEventMulticaster創(chuàng)建了事件廣播中心實(shí)例,但廣播中心還沒(méi)有持有任何監(jiān)聽(tīng)器觅够,這步主要完成監(jiān)聽(tīng)器的注冊(cè)胶背,以便事件下發(fā)時(shí),能找到對(duì)應(yīng)的監(jiān)聽(tīng)器喘先。
spring 通過(guò)如下方式獲取監(jiān)聽(tīng)器钳吟,并注冊(cè)的廣播中心:
- 獲取容器中靜態(tài)設(shè)置的監(jiān)聽(tīng)器注冊(cè)
- 通過(guò)beanFactory中查找監(jiān)聽(tīng)器注冊(cè)
registerListeners 還完成了(下發(fā)在事件機(jī)制初始化完成前的發(fā)布事件)功能,ApplicaitonContext將事件機(jī)制未初始化完成前發(fā)布的事件保存在earlyApplicationEvents集合中窘拯,當(dāng)前事件機(jī)制完成后統(tǒng)一下發(fā)到事件監(jiān)聽(tīng)器红且。實(shí)現(xiàn)就是在registerListeners方法中,代碼如下:
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
//通過(guò)事件廣播中心ApplicationEventMulticaster涤姊,下發(fā)事件到具體的監(jiān)聽(tīng)器ApplicationListener
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
ApplicaitonContext事件發(fā)布
//類 AbstractApplicationContext
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
//當(dāng)事件機(jī)制未初始化完成前暇番,將下發(fā)的事件保存在集合中,等待事件機(jī)制初始化完成后統(tǒng)一下發(fā)
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
// 事件機(jī)制初始化完成思喊,調(diào)用事件廣播中心下發(fā)事件
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// 將事件透?jìng)鞯礁干舷挛沫h(huán)境
// Publish event via parent context as well...
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
ApplicaitonContext繼承事件發(fā)布者接口壁酬,具有了事件發(fā)布的功能,ApplicaitonContext事件發(fā)布完成如下操作:
- 事件機(jī)制未初始化完成恨课,將事件保存到set集合舆乔。
- 事件機(jī)制初始化完成,調(diào)用事件廣播器庄呈,發(fā)布事件
- 將事件透?jìng)鞯礁讣?jí)上下問(wèn)環(huán)境ApplicaitonContext
事件機(jī)制初始化總結(jié): ApplicaitonContext 的refresh方法調(diào)用完成后蜕煌,就完成了整個(gè)事件機(jī)制的初始化工作,并將上下文中未下發(fā)到監(jiān)聽(tīng)器的事件統(tǒng)一通過(guò)事件廣播中心下發(fā)到事件監(jiān)聽(tīng)器诬留。