国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

notebin / 2751人閱讀

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

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

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

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

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

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

setter方式單例,默認方式

setter方式原型,prototype

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

Spring容器會將每一個正在創(chuàng)建的Bean 標識符放在一個“當前創(chuàng)建Bean池”中,Bean標識符在創(chuàng)建過程中將一直保持在這個池中。

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

首先我們先初始化三個Bean。

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

我們都把這三個Bean交給Spring管理,并用有參構造實例化。

下面是測試類:

publicclassTest{

publicstaticvoidmain(String[] args){

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

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

}

}

執(zhí)行結(jié)果報錯信息為:

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

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

如果大家理解開頭那句話的話,這個報錯應該不驚訝,Spring容器先創(chuàng)建單例StudentA,StudentA依賴StudentB,然后將A放在“當前創(chuàng)建Bean池”中,此時創(chuàng)建StudentB,StudentB依賴StudentC ,然后將B放在“當前創(chuàng)建Bean池”中,此時創(chuàng)建StudentC,StudentC又依賴StudentA, 但是,此時Student已經(jīng)在池中,所以會報錯,,因為在池中的Bean都是未初始化完的,所以會依賴錯誤 ,(初始化完的Bean會從池中移除)

第二種:setter方式單例,默認方式

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

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

修改配置文件為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方式就不報錯了呢 ?

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

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

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

第三種:setter方式原型,prototype

修改配置文件為:

測試用例:

publicclassTest{

publicstaticvoidmain(String[] args){

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

//此時必須要獲取Spring管理的實例,因為現(xiàn)在scope="prototype" 只有請求獲取的時候才會實例化對象

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?

為什么原型模式就報錯了呢 ?

對于“prototype”作用域Bean,Spring容器無法完成依賴注入,因為“prototype”作用域的Bean,Spring容器不進行緩存,因此無法提前暴露一個創(chuàng)建中的Bean。

感謝您耐心看完的文章

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

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/74638.html

相關文章

  • JS中輕松遍歷對象屬性幾種方式

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

    isLishude 評論0 收藏0
  • vue組件通信幾種方式

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

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

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

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

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

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

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

    ztyzz 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<