Date 10.06 pm Point 完成beanfactory中單例bean的初始化 beanFactory.preInstantiateSingletons() 1. 拿到所有的bean定義信息(在 中,遍歷list 2. 獲取到bean的定義信息 3. 如果這個bean不是抽象,是單例,不是 ...
Date 10.06 pm
Point
完成beanfactory中單例bean的初始化
beanFactory.preInstantiateSingletons()
- 拿到所有的bean定義信息(在
beanDefinitionNames
中,遍歷list - 獲取到bean的定義信息
- 如果這個bean不是抽象,是單例,不是懶載入的
判斷這個bean是否factorybean(判斷這個bean有沒有實現factoryBean介面),是的話,用工廠裡面的方法去創建bean。
- 調用
getbean(&beanname)
獲取到beanFactory對象。
- 調用
- 調用
getBean(beanName)
創建bean- 調用
doGetBean()
transformedBeanName
進入這個方法將之前工廠bean的首碼去除,將別名轉成正式的名稱getSingleton
檢測單例緩存中是否有已構建的單實例bean,有就直接返回這個單例bean
所有實例過的單例bean都會在這註冊,檢查的時候還會判斷當前bean有沒有在創建過程中。如果有的話,會在/** Cache of singleton objects: bean name to bean instance. */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
earlySingletonObjects
去獲取,要是這個還是沒有獲取到的話,會去singletonFactories
這個map中去獲取,要是獲取到的話就刪除singletonFactories
中的bean,轉而在earlySingletonObjects
這個map裡面去註冊- 沒有獲取到bean(開始創建bean的流程)
- 就先判斷下我們是不是正在創建這個bean的實例,避免迴圈引用的問題。
- 獲取bean的父工廠(這個主要是如果有Springmvc的話 可能會有這種父子工廠)這個父工廠要是能獲取到的話,又會去調用父工廠的dogetbean方法,獲取不到父工廠的話直接下一步
- 標記當前bean已經創建,大概就是把當前beanname放到
Collections.newSetFromMap(new ConcurrentHashMap<>(256))
裡面,防止多線程的時候多次創建單例bean - 獲取bean的定義信息
- 獲取bean所依賴的其他bean,如果有,還是調用getbean的方式去構建那些依賴的bean
- 如果這個bean是單例bean,回掉
createBean
,開始單例bean創建- 拿到bean的定義信息
- 解析bean的定義的類型,檢查這個定義信息中的beanClass是不是為空
- 檢測是否有bean方法被重寫,有的話準備重寫這個bean方法(也是檢查bean定義信息裡面的
methodOverrides
這個屬性有沒有值) - 讓BeanPostProcessor提前攔截,返回代理對象
resolveBeforeInstantiation()
- 先根據定義信息中的
beforeInstantiationResolved
判斷初始化之前有沒有處理,有的話就不進入這個processor中了, - 然後判斷這個值是不是由application定義的 和 判斷當前factory中已經有了
InstantiationAwareBeanPostProcessor
這個processor了,然後去獲取這個bean的目標class,然後調用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
啟動前置處理器,然後如果返回的bean有值的話,再調用applyBeanPostProcessorsAfterInitialization
後置處理器,然後將bean定義信息中beforeInstantiationResolved
這個參數賦值成這個返回的bean,然後返回這個bean
- 先根據定義信息中的
- 調用