注:本系列源碼分析基於spring 5.2.2.RELEASE,本文的啓動流程針對於
annotation
註解方式,gitee倉庫鏈接:spring-framework.
接上文,我們繼續分析spring的啓動流程。
7. 國際化: initMessageSource()
這個方法是用來初始化MessageSource
的,內容如下:
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
...
/**
* 初始化 MessageSource
*/
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果beanFactory中存在MessageSource,設置其 ParentMessageSource
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(
MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// 設置ParentMessageSource
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
}
// 如果beanFactory中不存在MessageSource,就 創建-設置-註冊
else {
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
// 設置ParentMessageSource
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
}
}
/**
* 返回父容器的 messageSource
*/
@Nullable
protected MessageSource getInternalParentMessageSource() {
return (getParent() instanceof AbstractApplicationContext ?
((AbstractApplicationContext) getParent()).messageSource : getParent());
}
...
}
可以看到,整個方法主要是操作MessageSource
,主要邏輯爲:如果已經存在MessageSource
了,就設置一些屬性;否則就創建MessageSource
,並設置些 屬性,最後註冊到beanFactory
中。
關於MessageSource
的具體作用,本文就不展開了。
8. 初始化事件廣播器:initApplicationEventMulticaster()
AbstractApplicationContext#initApplicationEventMulticaster
代碼如下:
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果用戶配置了自定義事件廣播器,就使用用戶的
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
ApplicationEventMulticaster.class);
}
else {
// 用戶沒有配置廣播器,就使用默認的事件廣播器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
this.applicationEventMulticaster);
}
}
這塊邏輯也很簡單,如果已存在事件廣播器,就使用已存在的,否則就創建一個。關於ApplicationEventMulticaster
,主要就是用來廣播事件的,更多關於事件的內容,可以參考spring探祕之spring 事件機制.
9. 擴展點:onRefresh()
AbstractApplicationContext#onRefresh
是spring提供的一個擴展點,方法並無內容:
protected void onRefresh() throws BeansException {
}
如果需要處理特定的操作,可以在子類中實現。
當前使用的ApplicationContext
是AnnotationConfigApplicationContext
,並無onRefresh()
方法,就不過多分析了。
10. 註冊事件監聽器:registerListeners()
AbstractApplicationContext#registerListeners
相關代碼如下:
AbstractApplicationContext
/** 這裏就是用來存放監聽器的 */
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
/** 返回當前所有的監聽器 */
public Collection<ApplicationListener<?>> getApplicationListeners() {
return this.applicationListeners;
}
/**
* 添加監聽器
*/
public void addApplicationListener(ApplicationListener<?> listener) {
Assert.notNull(listener, "ApplicationListener must not be null");
if (this.applicationEventMulticaster != null) {
this.applicationEventMulticaster.addApplicationListener(listener);
}
this.applicationListeners.add(listener);
}
/**
* 註冊監聽器
*/
protected void registerListeners() {
// 先添加手動set的一些監聽器
// getApplicationListeners() 獲取的監聽器基本是通過調用 addApplicationListener(...) 添加的
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 獲取取到監聽器的名稱,設置到廣播器
// 此時獲取的監聽器是從 beanFactory 中獲取的,即是spring通過包掃描得到的
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 如果存在早期應用事件,廣播
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
// 廣播早期事件
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
這個方法的流程大致如下:
- 添加
AbstractApplicationContext#applicationListeners
中的監聽器到ApplicationEventMulticaster
中 - 從
beanFactory
獲取監聽器的beanName
,添加到ApplicationEventMulticaster
中 - 如果有早期事件,就進行廣播
關於spring的事件,本文並不打算展開,如果想了解更多,可參考spring探祕之spring 事件機制.
本文的分析就到這裏了。
本文原文鏈接:https://my.oschina.net/funcy/blog/4892120 ,限於作者個人水平,文中難免有錯誤之處,歡迎指正!原創不易,商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
本系列的其他文章