spring為什么不能只用一二級緩存來解決循環依賴?


Spring bean注入流程
類實例化 -> 屬性注入 -> 執行初始化方法 -> (如果有需要)生成代理對象 -> 使用

二級緩存存在的問題
舉例說明:A、B兩個類相互依賴,初始化A的時候,

第一步實例化A完成(原始實例放入二級緩存),注入依賴屬性B,一級緩存查詢B沒有,二級緩存查詢B沒有,

初始化B(放入緩存),注入依賴屬性A,一級緩存查詢A沒有,二級緩存查詢A注入(此時A是原始實例,未被代理),生成代理對象B,移入一級緩存,繼續A屬性注入(B的代理對象),A初始化完成。

B中的依賴對象A是未代理的,存在問題(環境中存在代理和未代理的兩種類型的同一個對象A)。

如果上述流程放入二級緩存的是代理對象,則和spring bean生成流程(實例最后生成代理對象)相悖。

三級緩存解決的問題
A、B兩個類相互依賴,初始化A的時候,第一步實例化A完成(生成對象工廠實例放入三級緩存),注入依賴屬性B,一級緩存查詢B沒有,二級緩存查詢B沒有,

初始化B(生成對象工廠實例放入三級緩存),注入依賴屬性A,一級緩存查詢A沒有,二級緩存查詢A沒有,三級緩存查詢到A的對象工廠,生成A的代理對象,放入到二級緩存,注入A的代理對象完成,生成代理對象B,移入一級緩存。

繼續A屬性注入(B的代理對象),A初始化,生成A的代理對象,發現A的代理對象已存在,則跳過,放入一級緩存。此時A的代理對象也是提前生成的,但是僅針對循環依賴提前生成。

三級緩存正常生成流程

第一步實例化A完成(生成對象工廠實例放入三級緩存,此時雖然放入三級緩存,但沒有生成代理對象),注入屬性,執行初始化方法,生成代理對象,移入一級緩存。
其中創建AOP代理對象的子類是AbstractAutoProxyCreator,它實現了postProcessAfterInitialization方法,先判斷初始化完成后的bean是否已經被動態代理,若已處理過,則直接返回,如果不需要動態代理,也直接返回;若需要處理,則生成動態代理,保存到一級緩存中。

Spring AOP代理對象創建流程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM