十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
這篇文章主要講解了“怎么理解Spring源碼循環(huán)依賴”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么理解Spring源碼循環(huán)依賴”吧!
在法庫(kù)等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司 網(wǎng)站設(shè)計(jì)制作按需網(wǎng)站開發(fā),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),全網(wǎng)營(yíng)銷推廣,外貿(mào)營(yíng)銷網(wǎng)站建設(shè),法庫(kù)網(wǎng)站建設(shè)費(fèi)用合理。
Spring是怎么去解決循環(huán)依賴的
1.什么是循環(huán)依賴
這個(gè)詞,阿粉聽到的時(shí)候,肯定和大家的反應(yīng)一樣的,循環(huán),依賴,那是不是 A 引用了 B ,而此時(shí) B 引用了 C,而 C 呢又引用了A,于是一個(gè)三角戀的關(guān)系出現(xiàn)了。
那么用代碼來表示的話,是怎么表示的呢?
public class ClassTestA { private ClassTestB classTestB; public void a(){ classTestB.b(); } public ClassTestB getClassTestB() { return classTestB; } private void setClassTestB(ClassTestB classTestB){ this.classTestB = classTestB; } } public class ClassTestB { private ClassTestC classTestC; public void b(){ classTestC.c(); } public ClassTestC getClassTestC() { return classTestC; } private void setClassTestC(ClassTestC classTestC){ this.classTestC = classTestC; } } public class ClassTestC { private ClassTestA classTestA; public void c(){ classTestA.a(); } public ClassTestA getClassTestA() { return classTestA; } private void setClassTestA(ClassTestA classTestA){ this.classTestA = classTestA; } }
2.循環(huán)依賴會(huì)出現(xiàn)什么問題
在阿粉的印象中,循環(huán)依賴最直接的問題就是會(huì)出現(xiàn)在對(duì)象的實(shí)例化上面,創(chuàng)建對(duì)象的時(shí)候,如果在Spring的配置中加入這種 A 依賴 B ,B 依賴 C,C 依賴 A 的話,那么最終創(chuàng)建 A 的實(shí)例對(duì)象的時(shí)候,會(huì)出現(xiàn)錯(cuò)誤。
而如果這種循環(huán)調(diào)用的依賴不去終結(jié)掉他的話,那么就相當(dāng)于一個(gè)死循環(huán),就像阿粉前幾天的在維護(hù)那個(gè) “十六年”之前的項(xiàng)目的時(shí)候,各種內(nèi)存溢出,表示內(nèi)心很壓抑呀。
而 Spring 中也將循環(huán)依賴的處理分成了不同的幾種情況,阿粉帶大家來看一下吧。
3.Spring循環(huán)依賴處理一 (構(gòu)造器循環(huán)依賴)
構(gòu)造器循環(huán)依賴的意思就是說,通過構(gòu)造及注入構(gòu)成的循環(huán)依賴,而這種依賴的話,是沒有辦法解決的,如果你敢強(qiáng)行依賴,不要意思,出現(xiàn)了你久違的異常 BeanCurrentlyInCreationException 出現(xiàn)這個(gè)異常的時(shí)候,就是表示循環(huán)依賴的問題。
相信大家出現(xiàn)異常的時(shí)候,在看不懂為什么的時(shí)候,第一時(shí)間,復(fù)制異常信息,放在百度,或者Google上面查詢一下,BeanCurrentlyInCreationException 放在百度上,一目了然。
而在 Spring 的配置文件中,如果這么配置 A ,B ,C 的循環(huán)依賴的時(shí)候,在創(chuàng)建 A 的時(shí)候,發(fā)現(xiàn),構(gòu)造器需要 B 類,然后去創(chuàng)建 B ,而創(chuàng)建 B 的時(shí)候,發(fā)現(xiàn)又需要 C ,然后去創(chuàng)建 C ,創(chuàng)建的時(shí)候發(fā)現(xiàn),竟然需要 A ,于是又掉頭回去了,于是就形成了一個(gè)閉環(huán),沒有辦法創(chuàng)建。
而在這種情況下,Spring實(shí)例化bean是通過ApplicationContext.getBean()方法來進(jìn)行的。如果要獲取的對(duì)象依賴了另一個(gè)對(duì)象,那么其首先會(huì)創(chuàng)建當(dāng)前對(duì)象,然后通過遞歸的調(diào)用ApplicationContext.getBean()方法來獲取所依賴的對(duì)象,最后將獲取到的對(duì)象注入到當(dāng)前對(duì)象中。而和剛才阿粉說的一樣,創(chuàng)建了閉環(huán),所以就沒有辦法創(chuàng)建了。
4.Spring循環(huán)依賴處理二(setter循環(huán)依賴)
setter循環(huán)注入是指通過setter注入方式構(gòu)成的循環(huán)依賴。而這種方式,是Spring可以進(jìn)行解決的。
而對(duì)于這種使用setter注入造成的依賴是通過Spring容器來提前暴露剛完成的構(gòu)造注入器的bean來完成的,但是這時(shí)候還沒有完成其他的步驟的時(shí)候。
這個(gè)時(shí)候我們就需要提前暴露出來一個(gè)單例的工廠方法,讓其他的bean來引用這個(gè)bean,
addSingletonFactory(beanName,new ObjectFactory(){ public Object getObject() throws BeanException{ return getEarlyBeanReference(beanName,mbd,bean) } })
Spring在創(chuàng)建 A 的時(shí)候,根據(jù)無參構(gòu)造來創(chuàng)建 A,并且暴露出 ObjectFactory 用來返回一個(gè)提前暴露好的 bean 然后再進(jìn)行setter來注入,
同理的B和C都是這個(gè)樣子的,這個(gè)時(shí)候就能完成setter注入了。
5.Spring循環(huán)依賴處理三(作用域循環(huán)依賴)
阿粉帶大家看一下這個(gè)配置方式
而對(duì)于 “singleton”作用域的話,他是可以通過“setAllowCircularReference(false)”這種方式來進(jìn)制循環(huán)依賴的。
而且也是有缺陷的,這種方式只能解決單例作用域的bean循環(huán)依賴。
而Spring解決循環(huán)依賴的話,大家肯定會(huì)好奇,說是三級(jí)緩存,那么請(qǐng)找到你的Spring的源碼
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
感謝各位的閱讀,以上就是“怎么理解Spring源碼循環(huán)依賴”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)怎么理解Spring源碼循環(huán)依賴這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!