Java Spring循環(huán)依賴原理與bean的生命周期圖文案例詳解
前言
Spring是如何處理循環(huán)依賴的,又是怎么做到,互相注入對方的proxy bean而不是raw bean的?現(xiàn)在就分析一下
一、循環(huán)依賴是什么
Spring中放入兩個Service,分別是C1和C2,然后C1和C2又互為對方的成員變量。這種情況C1和C2就可以說是相互循環(huán)依賴了
二、源碼圖解
1. bean的主要生命周期圖解
上圖是一個沒有循壞依賴的bean的主要生命周期節(jié)點,下圖的循壞依賴可以結(jié)合該圖解一起看
2.循環(huán)依賴圖解
可以看到里面有一個很重要的邏輯:
當一個bean經(jīng)過所有的步驟之后,會去三個緩存里的二級緩存根據(jù)beanName獲取對象。
- 如果拿不到,就直接使用initializeBean方法之后生成的bean,然后放入到spring容器中
- 如果拿得到,就要對比執(zhí)行initializeBean前后的bean,如果bean相同,就用二級緩存里的對象作為bean放入到spring容器中,否則就報錯
- 所以spring3個緩存中,二級緩存存在的意義就是判斷該bean是否被循環(huán)依賴過,只有被循環(huán)依賴了,注入到其他bean的屬性里了,才會放入到二級緩存。
- 然后最后的判斷,判斷initializeBean方法執(zhí)行前后對象是否一致,其實就是為了判斷被循環(huán)依賴的bean在注入到其他bean和自己走完bean生命周期的是不是同一個object,如果不是同一個object,那就有問題,要報錯。
可以看到此處第二個參數(shù)allEarlyReference,這個參數(shù)就是用來區(qū)分從3個緩存里取bean的時候是否需要到3級緩存里取對象,此處為false,所以截止到2級為止。
3. 循環(huán)依賴處理完成之后
直接從Spring容器里拿的是c1 proxy或者c2 proxy,但是其實在屬性注入的時候,都是調(diào)用的raw對象的set方法,也就是proxy的target調(diào)用的set方法。
總結(jié)
循環(huán)依賴其實耐下功夫讀源碼,也沒有那么難。下次分享為什么循環(huán)依賴的其中一個類添加@Async有可能會導(dǎo)致注入失敗而拋異常
到此這篇關(guān)于Spring循環(huán)依賴原理與bean的生命周期圖文案例詳解的文章就介紹到這了,更多相關(guān)Spring循環(huán)依賴原理與bean的生命周期內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA中方法的聲明及使用方式(繼承、多態(tài)、封裝)
這篇文章主要介紹了JAVA中方法的聲明及使用方式(繼承、多態(tài)、封裝),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02SpringBootAdmin+actuator實現(xiàn)服務(wù)監(jiān)控
這篇文章主要為大家詳細介紹了SpringBootAdmin+actuator實現(xiàn)服務(wù)監(jiān)控,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01SpringBoot集成WebSocket實現(xiàn)前后端消息互傳的方法
這篇文章主要介紹了SpringBoot集成WebSocket實現(xiàn)前后端消息互傳的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2019-10-10