成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Spring-bean的幾種循環(huán)依賴方式

notebin / 2755人閱讀

摘要:如下圖注意,這里不是函數(shù)的循環(huán)調(diào)用,是對(duì)象的相互依賴關(guān)系。因此如果在創(chuàng)建過程中發(fā)現(xiàn)自己已經(jīng)在當(dāng)前創(chuàng)建池里時(shí)將拋出異常表示循環(huán)依賴而對(duì)于創(chuàng)建完畢的將從當(dāng)前創(chuàng)建池中清除掉。

什么是循環(huán)依賴?

循環(huán)依賴其實(shí)就是循環(huán)引用,也就是兩個(gè)或則兩個(gè)以上的bean互相持有對(duì)方,最終形成閉環(huán)。比如A依賴于B,B依賴于C,C又依賴于A。如下圖:

注意,這里不是函數(shù)的循環(huán)調(diào)用,是對(duì)象的相互依賴關(guān)系。循環(huán)調(diào)用其實(shí)就是一個(gè)死循環(huán),除非有終結(jié)條件。

Spring中循環(huán)依賴場景有:

構(gòu)造器的循環(huán)依賴

setter方式單例,默認(rèn)方式

setter方式原型,prototype

第一種:構(gòu)造器參數(shù)循環(huán)依賴

Spring容器會(huì)將每一個(gè)正在創(chuàng)建的Bean 標(biāo)識(shí)符放在一個(gè)“當(dāng)前創(chuàng)建Bean池”中,Bean標(biāo)識(shí)符在創(chuàng)建過程中將一直保持在這個(gè)池中。

因此如果在創(chuàng)建Bean過程中發(fā)現(xiàn)自己已經(jīng)在“當(dāng)前創(chuàng)建Bean池”里時(shí)將拋出BeanCurrentlyInCreationException異常表示循環(huán)依賴;而對(duì)于創(chuàng)建完畢的Bean將從“當(dāng)前創(chuàng)建Bean池”中清除掉。

首先我們先初始化三個(gè)Bean。

OK,上面是很基本的3個(gè)類,,StudentA有參構(gòu)造是StudentB。StudentB的有參構(gòu)造是StudentC,StudentC的有參構(gòu)造是StudentA ,這樣就產(chǎn)生了一個(gè)循環(huán)依賴的情況,

我們都把這三個(gè)Bean交給Spring管理,并用有參構(gòu)造實(shí)例化。

下面是測試類:

publicclassTest{

publicstaticvoidmain(String[] args){

ApplicationContext context =newClassPathXmlApplicationContext("com/zfx/student/applicationContext.xml");

//System.out.println(context.getBean("a", StudentA.class));

}

}

執(zhí)行結(jié)果報(bào)錯(cuò)信息為:

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException:

Error creating beanwithname"a": Requested beaniscurrentlyincreation:Isthere an unresolvable circular reference?

如果大家理解開頭那句話的話,這個(gè)報(bào)錯(cuò)應(yīng)該不驚訝,Spring容器先創(chuàng)建單例StudentA,StudentA依賴StudentB,然后將A放在“當(dāng)前創(chuàng)建Bean池”中,此時(shí)創(chuàng)建StudentB,StudentB依賴StudentC ,然后將B放在“當(dāng)前創(chuàng)建Bean池”中,此時(shí)創(chuàng)建StudentC,StudentC又依賴StudentA, 但是,此時(shí)Student已經(jīng)在池中,所以會(huì)報(bào)錯(cuò),,因?yàn)樵诔刂械腂ean都是未初始化完的,所以會(huì)依賴錯(cuò)誤 ,(初始化完的Bean會(huì)從池中移除)

第二種:setter方式單例,默認(rèn)方式

如果要說setter方式注入的話,我們最好先看一張Spring中Bean實(shí)例化的圖

如圖中前兩步驟得知:Spring是先將Bean對(duì)象實(shí)例化之后再設(shè)置對(duì)象屬性的

修改配置文件為set方式注入

下面是測試類:

publicclassTest{

publicstaticvoidmain(String[] args){

ApplicationContext context =newClassPathXmlApplicationContext("com/zfx/student/applicationContext.xml");

System.out.println(context.getBean("a", StudentA.class));

}

}

打印結(jié)果為:

com.zfx.student.StudentA@1fbfd6

為什么用set方式就不報(bào)錯(cuò)了呢 ?

我們結(jié)合上面那張圖看, Spring先是用構(gòu)造實(shí)例化 Bean對(duì)象 ,此時(shí)Spring會(huì)將這個(gè)實(shí)例化結(jié)束的對(duì)象放到一個(gè)Map中,并且Spring提供了獲取這個(gè)未設(shè)置屬性的實(shí)例化對(duì)象引用的方法。

結(jié)合我們的實(shí)例來看,,當(dāng)Spring實(shí)例化了StudentA、StudentB、StudentC后,緊接著會(huì)去設(shè)置對(duì)象的屬性,此時(shí)StudentA依賴StudentB,就會(huì)去Map中取出存在里面的單例StudentB對(duì)象,以此類推,不會(huì)出來循環(huán)的問題嘍、

下面是Spring源碼中的實(shí)現(xiàn)方法。以下的源碼在Spring的Bean包中的DefaultSingletonBeanRegistry.java類中

第三種:setter方式原型,prototype

修改配置文件為:

測試用例:

publicclassTest{

publicstaticvoidmain(String[] args){

ApplicationContext context =newClassPathXmlApplicationContext("com/zfx/student/applicationContext.xml");

//此時(shí)必須要獲取Spring管理的實(shí)例,因?yàn)楝F(xiàn)在scope="prototype" 只有請(qǐng)求獲取的時(shí)候才會(huì)實(shí)例化對(duì)象

System.out.println(context.getBean("a", StudentA.class));

}

}

打印結(jié)果:

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException:

Error creating beanwithname"a": Requested beaniscurrentlyincreation:Isthere an unresolvable circular reference?

為什么原型模式就報(bào)錯(cuò)了呢 ?

對(duì)于“prototype”作用域Bean,Spring容器無法完成依賴注入,因?yàn)椤皃rototype”作用域的Bean,Spring容器不進(jìn)行緩存,因此無法提前暴露一個(gè)創(chuàng)建中的Bean。

感謝您耐心看完的文章

順便給大家推薦一個(gè)Java技術(shù)交流群:710373545里面會(huì)分享一些資深架構(gòu)師錄制的視頻資料:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化、分布式架構(gòu)等這些成為架構(gòu)師必備的知識(shí)體系。還能領(lǐng)取免費(fèi)的學(xué)習(xí)資源,目前受益良多!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/74638.html

相關(guān)文章

  • JS中輕松遍歷對(duì)象屬性幾種方式

    摘要:當(dāng)普通對(duì)象要轉(zhuǎn)換成時(shí)就很有用,因?yàn)榉祷氐母袷脚c構(gòu)造函數(shù)接受的格式完全相同。使用常規(guī)的構(gòu)造函數(shù)可以將一個(gè)二維鍵值對(duì)數(shù)組轉(zhuǎn)換成一個(gè)對(duì)象。在和早期標(biāo)準(zhǔn)中,根本沒有指定屬性的順序。此函數(shù)還可以輕松地將純對(duì)象屬性映射到對(duì)象中。 為了保證的可讀性,本文采用意譯而非直譯。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 自身可枚舉屬性 Object.keys() 方法會(huì)返回一個(gè)...

    isLishude 評(píng)論0 收藏0
  • vue組件通信幾種方式

    摘要:雖然和都可以獲取組件實(shí)例,但是它們無法在跨級(jí)或兄弟間通信,這是它們的缺點(diǎn)。也就是在父組件中提供一個(gè)值,并且在需要使用的子孫組件中注入改值,即不僅僅是,只要是的子組件,無論隔多少代,都可以通過這個(gè)的方式注入。通過混入組件,實(shí)現(xiàn)組件間的通信。 寫在前面 vue 的組件化應(yīng)該是其最核心的思想了,無論是一個(gè)大的頁面還是一個(gè)小的按鈕,都可以被稱之為組件?;?Vue 的開發(fā),就是在寫一個(gè)個(gè)組件,...

    vspiders 評(píng)論0 收藏0
  • JavaScript幾種循環(huán)方式

    摘要:本教程解釋了現(xiàn)代中各種各樣的循環(huán)可能性目錄介紹提供了許多迭代循環(huán)的方法。引入了循環(huán),它結(jié)合了的簡潔性和破解能力注意使用。此循環(huán)在每次迭代中創(chuàng)建一個(gè)新范圍,因此我們可以安全地使用它而不是。 JavaScript提供了許多通過LOOPS迭代的方法。本教程解釋了現(xiàn)代JAVASCRIPT中各種各樣的循環(huán)可能性 showImg(https://segmentfault.com/img/bVbfH...

    Allen 評(píng)論0 收藏0
  • JavaScript幾種循環(huán)方式

    摘要:本教程解釋了現(xiàn)代中各種各樣的循環(huán)可能性目錄介紹提供了許多迭代循環(huán)的方法。引入了循環(huán),它結(jié)合了的簡潔性和破解能力注意使用。此循環(huán)在每次迭代中創(chuàng)建一個(gè)新范圍,因此我們可以安全地使用它而不是。 JavaScript提供了許多通過LOOPS迭代的方法。本教程解釋了現(xiàn)代JAVASCRIPT中各種各樣的循環(huán)可能性 showImg(https://segmentfault.com/img/bVbfH...

    piapia 評(píng)論0 收藏0
  • JavaScript幾種循環(huán)方式

    摘要:本教程解釋了現(xiàn)代中各種各樣的循環(huán)可能性目錄介紹提供了許多迭代循環(huán)的方法。引入了循環(huán),它結(jié)合了的簡潔性和破解能力注意使用。此循環(huán)在每次迭代中創(chuàng)建一個(gè)新范圍,因此我們可以安全地使用它而不是。 JavaScript提供了許多通過LOOPS迭代的方法。本教程解釋了現(xiàn)代JAVASCRIPT中各種各樣的循環(huán)可能性 showImg(https://segmentfault.com/img/bVbfH...

    ztyzz 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<