初始化時(shí)執(zhí)行的類為:AbstractApplicationContext
方法是這個(gè):
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
/**
*初始化一些容器所需變量,解析${}占位符變量
*/
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
/**
*核心
* 1.初始化bean工廠(包括一些自定義的工廠特征)
*2.loadBeanDefinitions(解析xml中bean為BeanDefinition)
2.1通過讀取xml配置文件將配置中標(biāo)簽在中的元素,解析成documet(類似html的document)
2.2遍歷document中的元素標(biāo)簽,并解析成BeanDefinition數(shù)據(jù)結(jié)構(gòu)
2.3將解析后的BeanDefinition數(shù)據(jù)結(jié)構(gòu),注冊到bean工廠的beanDefinitionMap中,并將beanName放入beanDefinitionNames中。2.3中如果發(fā)現(xiàn)容器已經(jīng)在創(chuàng)建bean實(shí)例了,
那么需要做額外的操作,這里有待補(bǔ)充。另外,此處還涉及manualSingletonNames這個(gè)人工單例記錄的list中,有待補(bǔ)充。如果該bean有重復(fù)定義,那么也有額外的處理。
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
/**
*配置beanfactory的一些參數(shù),比如類加載器、后處理器等等
*/
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
/**
*向beanFactory注冊一個(gè)servlet相關(guān)的后處理器
*/
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
/**
*執(zhí)行beanFactory后處理器,beanFactory后處理器保存在beanFactoryPostProcessors
*/
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
/**
*遍歷beanDefinitionNames找出實(shí)現(xiàn)了BeanPostProcessor的bean,并且最終都將其注冊到beanPostProcessors
*注:BeanPostProcessor根據(jù)其實(shí)現(xiàn)的接口區(qū)分為:priorityOrderedPostProcessors(PriorityOrdered),
internalPostProcessors(MergedBeanDefinitionPostProcessor),
orderedPostProcessorNames(Ordered),
nonOrderedPostProcessorNames(僅BeanPostProcessor)
區(qū)分的目的是這些在后期執(zhí)行時(shí)是需要考慮處理順序的
*/
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
/**
*初始化spring消息源
*/
initMessageSource();
// Initialize event multicaster for this context.
/**
*初始化spring應(yīng)用事件廣播
*/
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
/**
*初始化其他的特殊的上下文類,比如:ThemeSource,不知道有什么用
*/
onRefresh();
// Check for listener beans and register them.
//檢查注冊事件監(jiān)聽器,保存在applicationListeners
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
/**
*實(shí)例化其他非懶初始化的單例bean
*核心:
*遍歷所有bean-->判斷是否需要生成動(dòng)態(tài)代理-->需要:生成代理返回jdk + cglib
不需要:在bean實(shí)例化之前執(zhí)行實(shí)例化前beanPostProcessor-->bean實(shí)例化(反射)-->執(zhí)行實(shí)例化前beanPostProcessor
*/
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}