一.三級緩存的作用
? ? 在了解Bean的初始化之前,要先了解Bean的三級緩存?以及各自的作用
一級緩存(singletonObjects):單例池?
二級緩存(earlySingletonObjects):早期單例對象? (反射生成的對象?可能屬性還沒有填充完畢,執(zhí)行過了Bean的后置處理器?以及aop生成的? ?二級緩存是為了對象復用)
三級緩存(singletonFactories):單例工廠對象?用于反射生成對象
三級緩存是為了解決循環(huán)依賴而產(chǎn)生的(使用三級緩存而不是用二級緩存是因為?一級緩存中單例池為了保證對象的單一性? 即是?只存完整的對象?而不是既有完整對象?又有不完整對象):
使用場景:ABean?依賴屬性BBean?同樣bBean也依賴ABean如下:

解決過程如下:
1,lagouBean實例化?實例化過程中檢測有沒有依賴ItBean或其他Bean?沒有則直接完成所有屬性注入放在?單例池中?如果有依賴其他Bean?則放入單例工廠池等待其他依賴Bean注入
2.依賴屬性ItBean?實例化,發(fā)現(xiàn)itBean含有依賴屬性含有依賴屬性lagoubean?將itbean放入單例工廠池,?同時從單例工廠池中取出lagoubean完成itBean注入,
3.在上述過程中?獲取lagouBean?時候?將反射生成對象放入二級緩存,以備復用?在itBean完成屬性注入后?刪除單例工廠池中的工廠對象
4.lagouBean完成itBean屬性注入?將對象放入單例池?同時刪除二級緩存的對象

二.?bean的實例化過程
Bean創(chuàng)建?流程??在AbstractApplicationContext#refresh()?法的finishBeanFactoryInitialization(beanFactory) 處

進?finishBeanFactoryInitialization

繼續(xù)進?DefaultListableBeanFactory類的preInstantiateSingletons?法,我們找到下?部分的代碼,看到??Bean或者普通Bean,最終都是通過getBean的?法獲取實例

繼續(xù)跟蹤下去,我們進?到了AbstractBeanFactory類的doGetBean?法,

該方法?嘗試從緩存中獲取對象?在循環(huán)依賴中要用到

如果是第一次創(chuàng)建,則進入createBean方法

接著進?到AbstractAutowireCapableBeanFactory類的?法,找到以下代碼部分



所以這就是構造器注入不能解決循環(huán)依賴的原因?
下面是bean的屬性填充?以及后置處理器

三? 循環(huán)依賴源碼解析
實例化danlibean過程中會存在循環(huán)依賴

進入createBean方法后?可以看到將實力好的對象放入了三級緩存? 此時是沒有進行屬性注入的

然后進入

進入方法最下面的applyPropertyValues方法

可以看到他依賴了ItBean? 進入valueResolver.resolveValueIfNecessary方法

進入resolveReference?方法

從工廠中取ItBean

進入后?其實還是doCreateBean方法?在這里初始化bean并放入單例池?供lagouBean后續(xù)使用
同樣進入getSingleton?方法?過程中執(zhí)行doCreateBean?在該方法中完成依賴注入? 同樣執(zhí)行

然后進行屬性的注入獲取lagouBean

進入方法后

此時三級緩存中是有值得

也可以看出三級緩存機構

獲取到Ilagoubean?并移除三級緩存中數(shù)據(jù)

二級緩存的數(shù)據(jù)類型是

實例化完成后進入getSingleton?將itbean放入一級緩存


一級緩存結構

此時完成itbean注冊
此時回到lagoubean注冊流程

后續(xù)操作完成放置到一級緩存中