### 一蔫缸、一級(jí)緩存(singletonObjects)
1. **作用**:存儲(chǔ)已經(jīng)完全初始化的單例Bean對(duì)象统倒。
2. **數(shù)據(jù)結(jié)構(gòu)**:一個(gè)Map<String, Object>,鍵是bean的名稱两踏,值是bean實(shí)例计寇。
3. **說明**:當(dāng)bean完全創(chuàng)建并初始化完成后扩淀,它就會(huì)被放入一級(jí)緩存中吠撮,表示該bean可供整個(gè)應(yīng)用程序使用伊滋。
### 二洋幻、二級(jí)緩存(earlySingletonObjects)
1. **作用**:存儲(chǔ)提前暴露的單例Bean郁轻,即在bean實(shí)例化過程中部分初始化好的對(duì)象。
2. **數(shù)據(jù)結(jié)構(gòu)**:同樣是一個(gè)Map<String, Object>,鍵是bean的名稱好唯,值是部分初始化的bean對(duì)象竭沫。
3. **說明**:在bean的創(chuàng)建過程中,如果某些依賴已經(jīng)創(chuàng)建好并且可以提供給其他bean使用骑篙,這些尚未完全初始化的bean會(huì)被放入二級(jí)緩存中蜕提,以供后續(xù)使用。
### 三靶端、三級(jí)緩存(singletonFactories)
1. **作用**:存儲(chǔ)bean創(chuàng)建的工廠方法谎势,即正在創(chuàng)建中的bean的工廠對(duì)象。
2. **數(shù)據(jù)結(jié)構(gòu)**:一個(gè)Map<String, ObjectFactory<?>>杨名,鍵是bean的名稱它浅,值是一個(gè)ObjectFactory實(shí)例,用于獲取正在創(chuàng)建中的bean镣煮。
3. **說明**:當(dāng)Spring遇到循環(huán)依賴問題姐霍,且目標(biāo)bean尚未初始化時(shí),它會(huì)將一個(gè)工廠方法放入三級(jí)緩存中典唇。后續(xù)通過這個(gè)工廠方法來生成正在創(chuàng)建中的bean镊折。
### 四、三級(jí)緩存如何解決循環(huán)依賴
Spring解決循環(huán)依賴的關(guān)鍵在于提前暴露和工廠方法的使用介衔,具體流程如下:
1. **第一次實(shí)例化bean**:當(dāng)Spring需要實(shí)例化一個(gè)bean時(shí)恨胚,會(huì)先檢查該bean是否已經(jīng)在一級(jí)緩存中。如果存在炎咖,則直接返回赃泡。如果不存在,則會(huì)開始創(chuàng)建這個(gè)bean乘盼。
2. **提前暴露部分初始化的bean**:在創(chuàng)建過程中升熊,Spring會(huì)把已經(jīng)部分初始化(例如構(gòu)造函數(shù)已經(jīng)調(diào)用完)的bean放入二級(jí)緩存中。這樣绸栅,如果其他bean依賴于這個(gè)bean级野,能夠獲取到該bean的部分初始化實(shí)例(通常是一個(gè)代理對(duì)象)。
3. **循環(huán)依賴解決**:假設(shè)有bean A和bean B粹胯,A依賴B蓖柔,而B又依賴A。Spring會(huì)先實(shí)例化A风纠,并把A的工廠方法放入三級(jí)緩存中况鸣。此時(shí),A還沒有完全初始化竹观,但它已經(jīng)暴露出一個(gè)工廠方法镐捧,其他依賴它的bean(例如B)可以通過工廠方法獲取到A的實(shí)例。當(dāng)Spring需要初始化B時(shí),發(fā)現(xiàn)B依賴A愤估,而A尚未完全初始化帮辟。這時(shí),Spring會(huì)通過三級(jí)緩存中的工廠方法獲取到A的實(shí)例玩焰,由于A的工廠方法已經(jīng)暴露由驹,Spring能夠獲取到一個(gè)提前暴露的部分實(shí)例(此時(shí)A還未完全初始化,但足夠滿足B的依賴)昔园,然后繼續(xù)初始化B蔓榄。在B初始化完成后,Spring會(huì)繼續(xù)完成A的初始化默刚。
4. **最終完成初始化**:一旦A和B的循環(huán)依賴問題解決后甥郑,Spring會(huì)將它們完全初始化并放入一級(jí)緩存中。