国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Spring】Spring的循環(huán)依賴以及解決方案

這篇具有很好參考價值的文章主要介紹了【Spring】Spring的循環(huán)依賴以及解決方案。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

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

? Spring循環(huán)依賴指的是兩個或多個Bean之間相互依賴,形成一個環(huán)狀依賴的情況。通俗的說,就是A依賴B,B依賴C,C依賴A,這樣就形成了一個循環(huán)依賴的環(huán)。

? Spring循環(huán)依賴通常會導(dǎo)致Bean無法正確地被實例化,從而導(dǎo)致應(yīng)用程序無法正常啟動或者出現(xiàn)異常。因此,Spring循環(huán)依賴是一種需要盡量避免的情況。

2. 常見形成原因

1. 構(gòu)造函數(shù)循環(huán)依賴

? 在使用構(gòu)造函數(shù)注入Bean時,如果兩個Bean之間相互依賴,就可能會形成構(gòu)造函數(shù)循環(huán)依賴,例如:

@Component
public class A {    
    private B b;    
	public A(B b) {     
        this.b = b;   
    }}
==============
@Component
public class B {   
    private A a;   
    public B(A a) {     
        this.a = a;  
    }}

上述代碼,A、B的構(gòu)造函數(shù)分別需要創(chuàng)建對方,A依賴B,B依賴A,它們之間形成了一個循環(huán)依賴。
當(dāng)Spring容器啟動時,它會嘗試先實例化A,但是在實例化A的時候需要先實例化B,而實例化B的時候需要先實例化A,這樣就形成了一個循環(huán)依賴的死循環(huán),從而導(dǎo)致應(yīng)用程序無法正常啟動。

2. 屬性循環(huán)依賴

? 在使用屬性注入Bean時,如果兩個Bean之間相互依賴,就可能會形成屬性循環(huán)依賴。例如:

@Component
public class A {   
    @Autowired    
    private B b;
}
=============
@Component
public class B {    
    @Autowired    
    private A a;
}

類似的,同樣Spring在實例化A時會注入B,而注入B時又需要注入A,形成循環(huán)依賴

3. Spring如何解決循環(huán)依賴

要了解如何解決Spring的循環(huán)依賴,就必須要從Spring對Bean的創(chuàng)建過程入手,從原理上去理解,而不是單純記憶

3.1 Spring 是如何創(chuàng)建Bean的?

spring循環(huán)依賴,學(xué)習(xí)記錄,Spring,spring,java,后端

? (1) 首先Spring容器啟動之后,會根據(jù)使用不同類型的Application Context,通過不同的方式去加載Bean配置,如xml方式、注解方式,將這些Bean配置加載到容器中,作為Bean定義包裝成BeanDefinition對象保存起來,為下一步創(chuàng)建Bean做準(zhǔn)備。

? (2) 根據(jù)加載的Bean定義信息,通過反射來創(chuàng)建Bean實例,如果是普通Bean,則直接創(chuàng)建Bean,如果是FactoryBean,說明真正要創(chuàng)建的對象為getObject()的返回值,調(diào)用getObject()將返回值作為Bean。

? (3) 目前已經(jīng)完成了Bean實例的創(chuàng)建,還需要對依賴的屬性進(jìn)行裝配,例如,平時開發(fā)中Controller中,往往需要將Service Bean注入進(jìn)來,循環(huán)依賴也是在這一步解決的,后面會詳細(xì)說明,如果通過@Autowired注解注入的成員變量,則會通過AutowiredAnnotationBeanPostProcessor后置處理器進(jìn)行注入,如果xml自動注入,則會根據(jù)按名字自動裝配和按類型自動裝配分別進(jìn)行處理。

? (4) 自動裝配完成后,將完整的Bean對象保存到Spring 緩存中,接下來進(jìn)入Bean的初始化流程,執(zhí)行Bean的后置處理器的前置處理方法,如果Bean本身實現(xiàn)了InitializingBean接口,就去執(zhí)行對應(yīng)的afterPropertiesSet()方法,最后再執(zhí)行Bean的后置處理器的后置處理方法。

3.2 Spring三級緩沖機(jī)制

1. Spring可以解決的依賴循環(huán)

回到上述的依賴循環(huán)案例,A、B相互依賴時,產(chǎn)生的循環(huán)依賴現(xiàn)象還需進(jìn)一步細(xì)分:

spring循環(huán)依賴,學(xué)習(xí)記錄,Spring,spring,java,后端

注意:只有單例的 Bean 存在循環(huán)依賴的情況,Spring才可以解決,原型(Prototype)情況下,Spring 會直接拋出異常。

? Spring 不支持基于構(gòu)造器注入的循環(huán)依賴。 但是假如 AB 循環(huán)依賴,如果一個是構(gòu)造器注入,一個是 setter 注入呢?

看看幾種情形:

spring循環(huán)依賴,學(xué)習(xí)記錄,Spring,spring,java,后端
第四種可以而第五種不可以的原因是 Spring 在創(chuàng)建 Bean 時默認(rèn)會根據(jù)自然排序進(jìn)行創(chuàng)建,所以 A 會先于 B 進(jìn)行創(chuàng)建。

簡單總結(jié),當(dāng)循環(huán)依賴的實例都采用 setter 方法注入的時候,Spring 可以支持,都采用構(gòu)造器注入的時候,不支持,構(gòu)造器注入和 setter 注入同時存在的時候,看天。

2. 三層緩存機(jī)制

bean的創(chuàng)建流程:

spring循環(huán)依賴,學(xué)習(xí)記錄,Spring,spring,java,后端

? 依賴注入就發(fā)生在第二步,屬性賦值,結(jié)合這個過程,Spring 通過三級緩存解決了循環(huán)依賴:

  1. 一級緩存 : Map<String,Object> singletonObjects,單例池,用于保存實例化、屬性賦值(注入)、初始化完成的 bean 實例
  2. 二級緩存 : Map<String,Object> earlySingletonObjects,早期曝光對象,用于保存實例化完成的 bean 實例
  3. 三級緩存 : Map<String,ObjectFactory<?>> singletonFactories,早期曝光對象工廠,用于保存 bean 創(chuàng)建工廠,以便于后面擴(kuò)展有機(jī)會創(chuàng)建代理對象。

spring循環(huán)依賴,學(xué)習(xí)記錄,Spring,spring,java,后端

我們來看一下三級緩存解決循環(huán)依賴的過程:

當(dāng) A、B 兩個類發(fā)生循環(huán)依賴時:
spring循環(huán)依賴,學(xué)習(xí)記錄,Spring,spring,java,后端

A 實例的初始化過程:

  1. 創(chuàng)建 A 實例,實例化的時候把 A 對象??放?三級緩存,表示 A 開始實例化了,雖然我這個對象還不完整,但是先曝光出來讓大家知道

spring循環(huán)依賴,學(xué)習(xí)記錄,Spring,spring,java,后端1

  1. A 注?屬性時,發(fā)現(xiàn)依賴 B,此時 B 還沒有被創(chuàng)建出來,所以去實例化 B
  2. 同樣,B 注?屬性時發(fā)現(xiàn)依賴 A,它就會從緩存里找 A 對象。依次從?級到三級緩存查詢 A,從三級緩存通過對象??拿到 A,發(fā)現(xiàn) A 雖然不太完善,但是存在,把 A 放??級緩存,同時刪除三級緩存中的 A,此時,B 已經(jīng)實例化并且初始化完成,把 B 放入?級緩存。

spring循環(huán)依賴,學(xué)習(xí)記錄,Spring,spring,java,后端2

  1. 接著 A 繼續(xù)屬性賦值,順利從?級緩存拿到實例化且初始化完成的 B 對象,A 對象創(chuàng)建也完成,刪除?級緩存中的 A,同時把 A 放??級緩存
  2. 最后,?級緩存中保存著實例化、初始化都完成的 A、B 對象

spring循環(huán)依賴,學(xué)習(xí)記錄,Spring,spring,java,后端5

所以,我們就知道為什么 Spring 能解決 setter 注入的循環(huán)依賴了,因為實例化和屬性賦值是分開的,所以里面有操作的空間。如果都是構(gòu)造器注入的化,那么都得在實例化這一步完成注入,所以自然是無法支持了。文章來源地址http://www.zghlxwxcb.cn/news/detail-857049.html

所以,我們就知道為什么 Spring 能解決 setter 注入的循環(huán)依賴了,因為實例化和屬性賦值是分開的,所以里面有操作的空間。如果都是構(gòu)造器注入的化,那么都得在實例化這一步完成注入,所以自然是無法支持了。

到了這里,關(guān)于【Spring】Spring的循環(huán)依賴以及解決方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Spring解決循環(huán)依賴

    Spring解決循環(huán)依賴

    目錄 什么是spring循環(huán)依賴 什么情況下循環(huán)依賴可以被處理? spring?如何解決循環(huán)依賴 創(chuàng)建A這個Bean的流程 答疑 疑問:在給B注入的時候為什么要注入一個代理對象? 初始化的時候是對A對象本身進(jìn)行初始化,而容器中以及注入到B中的都是代理對象,這樣不會有問題嗎? 三級

    2024年02月22日
    瀏覽(24)
  • Spring解決循環(huán)依賴問題

    Spring解決循環(huán)依賴問題

    例如,就是A對象依賴了B對象,B對象依賴了A對象。(下面的代碼屬于 屬性的循環(huán)依賴 ,也就是初始化階段的循環(huán)依賴,區(qū)別與底下 構(gòu)造器的循環(huán)依賴 ) 問題來了: A Bean創(chuàng)建 —— 依賴了 B 屬性 ——? 觸發(fā) B Bean創(chuàng)建 ——? B 依賴了 A 屬性 ——? 需要 A Bean(但A Bean還在創(chuàng)建

    2024年02月12日
    瀏覽(25)
  • 三級緩存---解決 Spring 循環(huán)依賴

    三級緩存---解決 Spring 循環(huán)依賴

    首先,什么是循環(huán)依賴?這個其實好理解,就是兩個 Bean 互相依賴,類似下面這樣: \\\"\\\"\\\" \\\"\\\"\\\" AService 和 BService 互相依賴: 一般來說,循環(huán)依賴有三種不同的形態(tài),上面就是其中一種。 另外兩種分別是三者依賴,如下圖: 這種循環(huán)依賴一般隱藏比較深,不易發(fā)覺。 還有自我依

    2024年02月16日
    瀏覽(23)
  • Spring如何解決循環(huán)依賴問題

    循環(huán)依賴問題在Spring中主要有三種情況: (1)通過構(gòu)造方法進(jìn)行依賴注入時產(chǎn)生的循環(huán)依賴問題。 (2)通過setter方法進(jìn)行依賴注入且是在多例(原型)模式下產(chǎn)生的循環(huán)依賴問題。 (3)通過setter方法進(jìn)行依賴注入且是在單例模式下產(chǎn)生的循環(huán)依賴問題。 在Spring中,只有第

    2024年02月06日
    瀏覽(17)
  • Spring怎么解決循環(huán)依賴問題?

    Spring怎么解決循環(huán)依賴問題?

    循環(huán)依賴是指 一個或多個對象之間存在直接或間接的依賴關(guān)系,這種依賴關(guān)系構(gòu)成一個環(huán)形調(diào)用 , 舉個例子 : A 依賴B , B依賴C , C依賴A , 這樣就形成了循環(huán)依賴; ? ①構(gòu)造器的循環(huán)依賴:這種依賴spring是處理不了的,直接拋出BeanCurrentlyInCreationException異常。 ②單例模式下的se

    2024年02月08日
    瀏覽(25)
  • Spring 能解決所有循環(huán)依賴嗎?

    Spring 能解決所有循環(huán)依賴嗎?

    以下內(nèi)容基于 Spring6.0.4。 看了上篇文章的小伙伴,對于 Spring 解決循環(huán)依賴的思路應(yīng)該有一個大致了解了,今天我們再來看一看,按照上篇文章介紹的思路,有哪些循環(huán)依賴 Spring 處理不了。 嚴(yán)格來說,其實也不是解決不了,所有問題都有辦法解決,只是還需要額外配置,這

    2024年02月17日
    瀏覽(22)
  • [Spring] 三級緩存解決循環(huán)依賴詳解

    [Spring] 三級緩存解決循環(huán)依賴詳解

    注冊一個bean對象的過程: Spring掃描class得到BeanDefinition – 根據(jù)得到的BeanDefinition去生成bean – 現(xiàn)根據(jù)class推斷構(gòu)造方法 – 根據(jù)推斷出來的構(gòu)造方法,反射,得到一個對象 – 填充初始對象中的屬性(依賴注入) – 如果原始對象種的某個方法被AOP了,那么要根據(jù)原始對象生成一

    2024年02月15日
    瀏覽(21)
  • Spring 是如何解決循環(huán)依賴的

    Spring 是如何解決循環(huán)依賴的

    1.什么是循環(huán)依賴? 所謂的循環(huán)依賴是指,A 依賴 B,B 又依賴 A,它們之間形成了循環(huán)依賴?;蛘呤?A 依賴 B,B 依賴 C,C 又依賴 A。它們之間的依賴關(guān)系如下: 2.通過手寫代碼演示理解Spring循環(huán)依賴 DEMO: 為什么需要二級緩存? 一級緩存和二級緩存相比: 二級緩存只要是為了分

    2024年02月03日
    瀏覽(19)
  • spring解決循環(huán)依賴的三級緩存

    實例化,對應(yīng)方法:AbstractAutowireCapableBeanFactory中的createBeanInstance方法,簡單理解就是new了一個對象。 屬性注入,對應(yīng)方法:AbstractAutowireCapableBeanFactory的populateBean方法,為實例化中new出來的對象填充屬性和注入依賴。 初始化,對應(yīng)方法:AbstractAutowireCapableBeanFactory的initialize

    2024年02月03日
    瀏覽(24)
  • Spring 怎么解決循環(huán)依賴的呢?

    Spring 怎么解決循環(huán)依賴的呢?

    Spring 循環(huán)依賴:簡單說就是自己依賴自己,或者和別的 Bean 相互依賴。 只有單例的 Bean 才存在循環(huán)依賴的情況, 原型 (Prototype)情況下,Spring 會直接拋出異常。原因很簡單,AB 循環(huán)依賴,A 實例化的時候,發(fā)現(xiàn)依賴 B,創(chuàng)建 B 實例,創(chuàng)建 B 的時候發(fā)現(xiàn)需要 A,創(chuàng)建 A1 實例……

    2024年02月09日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包