關(guān)于循環(huán)依賴有的同學(xué)寫的很好,貼出來:
https://www.cnblogs.com/tiger-fu/p/8961361.html
https://juejin.cn/post/6844903715602694152#heading-7
https://blog.csdn.net/LeoHan163/article/details/106343857
https://www.cnblogs.com/leeego-123/p/12165278.html
Spring中的循環(huán)依賴:
- 構(gòu)造器循環(huán)依賴
是否解決:通過構(gòu)造器注入構(gòu)成的循環(huán)依賴,此依賴是無法解決的,只能拋出BeanCurrentlyInCreationException異常表示循環(huán)依賴。
原因:創(chuàng)建A類時,構(gòu)造器需要B類,那將去創(chuàng)建B,在創(chuàng)建B類時又發(fā)現(xiàn)需要C類,則又去創(chuàng)建C,最終在創(chuàng)建C時發(fā)現(xiàn)又需要A,從而形成一個環(huán),沒辦法創(chuàng)建。
實現(xiàn)有循環(huán)依賴時拋出異常:
Spring容器會將每一個正在創(chuàng)建的Bean 標(biāo)識符放在一個“當(dāng)前創(chuàng)建Bean池(singletonsCurrentlyInCreation)”中,Bean標(biāo)識符在創(chuàng)建過程中將一直保持在這個池中。
因此如果在創(chuàng)建Bean過程中發(fā)現(xiàn)自己已經(jīng)在“當(dāng)前創(chuàng)建Bean池”里時將拋出BeanCurrentlyInCreationException異常表示循環(huán)依賴。
而對于創(chuàng)建完畢的Bean將從“當(dāng)前創(chuàng)建Bean池”中清除掉。
- 屬性注入循環(huán)依賴
prototype模式:有狀態(tài)的bean都使用prototype作用域,無狀態(tài)的一般都使用singleton單例作用域。
是否解決:"prototype"作用域bean,Spring容器無法完成依賴注入。
原因:“prototype”作用域的Bean,Spring容器不進(jìn)行緩存,因此無法提前暴露一個創(chuàng)建中的Bean。
singleton模式
是否解決:是的
單例屬性注入如何解決循環(huán)依賴
本質(zhì)上,是通過將半成品實體(實例化,但還未進(jìn)行屬性注入的實體)存放到map中實現(xiàn)的。
用到的map
1.singletonObjects 單例對象列表, beanName -> bean實例。
2.singletonFactories 單例工廠列表 beanName -> beanFactory。
3.earlySingletonObjects 循環(huán)對象依賴列表,對象在創(chuàng)建之后,進(jìn)行注入過程中,發(fā)現(xiàn)產(chǎn)生了循環(huán)依賴,那么會將對象放入到這個隊列,并且從singletonFactories中移除掉。
4.singletonsCurrentlyInCreation 正在創(chuàng)建的單例名稱隊列。
5.registeredSingletons 已經(jīng)創(chuàng)建成功的單例名稱列表。
假設(shè)A與B相互依賴
實例化A之后,此時:
singletonFactories 包含 A
registeredSingletons 包含A
singletonsCurrentlyInCreation 包含A
singletonObjects 不包含A
earlySingletonObjects 不包含A
發(fā)現(xiàn)A需要注入B,于是實例化B,之后發(fā)現(xiàn)B需要A,于是map中拿到A,此時:
singletonFactories 不包含 A
registeredSingletons 包含A
singletonsCurrentlyInCreation 包含A
singletonObjects 不包含A
earlySingletonObjects 包含A
B獲取了A,實例化、初始化完成,此時:
singletonFactories 不包含B
registeredSingletons 包含B
singletonsCurrentlyInCreation 不包含B
singletonObjects 包含B
earlySingletonObjects 不包含B
A繼續(xù)初始化,由于上面B初始化完成,所以可以獲得B,此時:
singletonFactories 不包含A
registeredSingletons 包含A
singletonsCurrentlyInCreation 不包含A
singletonObjects 包含A
earlySingletonObjects 包含A
主要使用了singletonFactories、earlySingletonObjects來解決循環(huán)依賴的問題。如果不是使用aop的情況下,使用一個map也可以解決循環(huán)依賴的問題。但是如果使用了aop,singletonFactories返回的代理對象每次都是不一樣的,所需需要引入earlySingletonObjects。