Spring原始碼窺探之:單例項Bean的建立過程
finishBeanFactoryInitialization(beanFactory);初始化剩下的所有的單例項(非懶載入)Bean(Instantiate all remaining (non-lazy-init) singletons.)
1. beanFactory.preInstantiateSingletons();初始化剩下的所有的單例項(非懶載入)Bean
1) 首先獲取所有BeanDefinition的名字List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
2) 根據名字獲取Bean的定義資訊RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
3) 再依次判斷RootBeanDefinition不是抽象的,是單例的,不是懶載入的
1> 判斷是不是工廠Bean,isFactoryBean(beanName),如果是的話,利用工廠來建立物件
2> 如果不是,就用getBean(beanName);來建立物件.
0. getBean(beanName)
1. doGetBean(name, null, null, false);
2. 先從快取中獲取單例項Bean,如果能獲取到說明這個Bean建立過(所有建立過的單例項Bean都會被快取起來)
Object sharedInstance = getSingleton(beanName);
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
3. 快取中沒有的話,就來建立物件.
4. 標記當前Bean已被建立
5. 獲取Bean的定義資訊
6. 獲取當前Bean依賴的其它Bean(dependsOn),如果有按照getBean()把依賴的Bean先創建出來。
7. 啟動單例項Bean的建立流程
1)createBean(beanName,mbd,args)
2)Object bean = resolveBeforeInstantiation(beanName, mbdToUse);讓BeanPostProcessor先攔截返回代理物件
InstantiationAwareBeanPostProcessor提前執行:
先觸發InstantiationAwareBeanPostProcessor介面中的postProcessBeforeInstantiation(beanClass, beanName);
如果有返回值,那麼再觸發InstantiationAwareBeanPostProcessor中的postProcessAfterInitialization(result, beanName);
3)如果InstantiationAwareBeanPostProcessor沒有返回代理物件
4)Object beanInstance = doCreateBean(beanName, mbdToUse, args);建立Bean
1. 【建立Bean的例項】instanceWrapper = createBeanInstance(beanName, mbd, args);建立Bean
利用工廠方法或者構造器來建立Bean的例項
2. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
呼叫MergedBeanDefinitionPostProcessor的bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);