應用上下文創(chuàng)建流程概覽

源碼剖析
- 創(chuàng)建Spring應用程序上下文
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
- 進入ClassPathXmlApplicationContext構造函數(shù)
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
(1)調(diào)用父類構造方法,創(chuàng)建Reslover,解析配置文件
(2)設置配置文件路徑到當前應用程序中
(3)開始調(diào)用refresh(),進行容器的創(chuàng)建
- 進入refresh()方法
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// 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();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
(1) prepareRefresh:做前期準備
- 設置容器的啟動時間
- 設置活躍狀態(tài)為true
- 設置關閉狀態(tài)為false
- 獲取Environment對象,并加載當前系統(tǒng)的屬性值到Environment對象中
- 準備監(jiān)聽器和事件對象的集合
(2) obtainFreshBeanFactory
創(chuàng)建容器并完成配置文件加載
(3) prepareBeanFactory
通過一系列的add, set, ignore, register開頭的方法,給容器對象進行賦值
(4) postProcessBeanFactory: 默認沒有實現(xiàn),留給子類去實現(xiàn)
(5) invokeBeanFactoryPostProcessors
可進行自由擴展,修改BeanFactory的相關信息。比如:ConfigurationClassPostProcessor, PropertySourcePlaceHolderConfigurer
(6) registerBeanPostProcessors
注冊BeanPostProcessor,完成spring自帶的或者用戶自定義的BeanPostProcessor的解析
(7) initMessageSource
進行國際化相關的操作
(8) initApplicationEventMulticaster
初始化事件廣播器
(9) onRefresh: 默認沒有實現(xiàn),由子類去定義
(10) registerListener: 注冊監(jiān)聽器,接收廣播的事件
(11) finishBeanFactoryInitialization:完成對象的實例化操作
從此方法開始進行對象的創(chuàng)建,包含實例化,初始化,循環(huán)依賴,AOP等核心邏輯的處理過程。
(12) finishRefresh
完成整個容器的啟動,所有對象都準備完成。清除上下午緩存,初始化生命周期處理器,并發(fā)送刷新完成事件。
Bean的創(chuàng)建
前面說到了在finishBeanFactoryInitialization()方法中會進行對象的創(chuàng)建。下面來進一步看下Bean是如何創(chuàng)建的:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
(1)setConversionService:設置類型轉換服務
(2)addEmbeddedValueResolver:設置內(nèi)置的值處理器
(3)freezeConfiguration:凍結BeanDefinition
(4)preInstantiateSingletons(關鍵步驟):
開始對象的實例化:
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
從容器中獲取所有的BeanDefinitionNames集合,從每個集合中獲取每一個元素,來進行對象的創(chuàng)建。
根據(jù)BeanName來獲取完整的BeanDefinition對象。再通過getBean()來獲取Bean對象,里面調(diào)用的doGetBean()。
這其中涉及到整個Bean的創(chuàng)建,屬性填充,實例化等一些列操作,大致流程如下:

這其中涉及到spring對Bean對象的三級緩存,后面會再來詳細說下這個問題。