阿里面試官居然不懂Spring是如何解決循環依賴的?

BeanPostProcessor的after方法中會完成動態代理對象的創建。

  • 在創建代理對象之前,是否需要原始對象?
    需要原始對象!

  • 若剛開始先創建了原始對象,然後又創建了代理對象,則對外暴露引用時,應該用原始對象還是用代理對象呢?
    程序是寫死的,沒那麼智能,說要判斷用什麼對象,所以我們需要保證,當bean需要被引用時,必須給出一個最終的結果:要麼是原始對象,要麼是代理對象,當生成代理對象時,原始對象會被覆蓋掉。

  • 怎麼確定對象什麼時候對外暴露或者說對外引用呢?
    無法確定!所以有了三級緩存這個騷操作!有了三級緩存,每次在創建完對象後,不是直接把對象放到一級或二級緩存,而是先將一個lambda表達式放到三級緩存中,當需要被引用時,會優先從三級緩存中獲取到lambda,然後根據lambda表達式處理結果判斷到底是原始對象還是代理對象。
    getEarlyBeanReference在此方法中已唯一確定了對外暴露的對象到底是原始對象還是代理對象。

當Bean產生循環依賴時,比如BeanA的構造方法依賴BeanB作爲成員需要注入,BeanB也依賴BeanA,你覺得會出現什麼問題呢?又有哪些解決方式呢?

通過set方法去處理,背後的原理其實是緩存。
主要解決方式:

三級緩存

singletonObjects

一級緩存, Cache of singleton objects
bean name --> bean instance。
存放完整對象。

earlySingletonObjects

二級緩存, Cache of early singleton objects
bean name --> bean instance 提前曝光的BEAN緩存。
存放半成品對象。

singletonFactories

三級緩存, Cache of singleton factories
bean name --> ObjectFactory。需要的對象被代理時,就必須使用三級緩存(否則二級就夠了)。解決循環依賴中存在aop的問題
存放 lambda 表達式和對象名稱的映射。

  • spring中已經有了循環依賴的解決方案,爲什麼項目中還會出現循環依賴的問題?
    spring中現有的解決循環依賴問題的方案只是一種預防機制, 當符合此情況的時候可以解決,但是在實際的場景中會存在很多不匹配的情況,構造器的循環依賴是無法解決的!

帶着aop的實現來重新走一下剛剛執行的邏輯, 體會各個對象在程序運行過程中的流轉過程,對象的三個緩存中的遷移過程,畫個圖,總結下,debug下,
起始斷點的入口在:finishBeanFactorylnitialization方法。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章