日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達者為師

網(wǎng)站首頁 編程語言 正文

spring如何解決循環(huán)依賴

作者:l1050188952 更新時間: 2022-09-25 編程語言

在解決循環(huán)依賴問題之前我們先了解一下什么是循環(huán)依賴

? ? ? ? 依賴就是Bean之間的引用關(guān)系,當引用互相持有時形成閉環(huán),這就是循環(huán)依賴。分為三種情況:1.自己依賴自己的直接依賴?

2.兩個bean對象之間的直接依賴

?

3.多個bean之間的簡介依賴

?

?依賴注入的時機在上一篇Bean的生命周期中我們有講到,實例化-->屬性賦值-->初始化

對于一個單例Bean來說整個容器只有一個,在初始化時解決循環(huán)依賴問題就非常方便,Spring是使用了三級緩存的形式解決的。

三級緩存:

singletonObjects:單例對象的cache(存儲器,快速,循環(huán)使用)單例池容器,緩存創(chuàng)建好的單例Bean的地方

earlySingletonObjects :提前曝光的單例對象的Cache(存儲器,快速,循環(huán)使用),早期曝光的單例對象,用于保存實例化后的Bean,此時的Bean還是不完整的

singletonFactories : 單例對象工廠的cache(存儲器,三級緩存),Bean的映射創(chuàng)建原始工廠,用于保存Bean的創(chuàng)建工廠

在創(chuàng)建Bean時先在一級緩存中獲取,代碼如下:

protected Object getSingleton(String beanName, boolean allowEarlyReference//是否允許拿對象) {
//在一級緩存獲取
  Object singletonObject = this.singletonObjects.get(beanName);
//沒獲取到
  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)//判斷當前Bean是否正在創(chuàng)建) {
   synchronized (this.singletonObjects) {
//二級緩存獲取
    singletonObject = this.earlySingletonObjects.get(beanName);
//二級緩存沒有
    if (singletonObject == null && allowEarlyReference) {
//三級緩存獲取
     ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
     if (singletonFactory != null) {
//在三級緩存獲取
      singletonObject = singletonFactory.getObject();
      this.earlySingletonObjects.put(beanName, singletonObject);
      this.singletonFactories.remove(beanName);
     }
    }
   }
  }
//返回以及或者二級或者三級緩存的singletonObject

  return singletonObject;
 }

從上面的代碼可以看出,Spring解決循環(huán)依賴問題中,singletonFactories 三級緩存時設(shè)計的關(guān)鍵,在Bean第一次創(chuàng)建時發(fā)現(xiàn)以來的Bean沒有,就會用構(gòu)造方法先將自己曝光在三級緩存中,等待依賴的Bean被創(chuàng)建存入一級緩存時,在進行創(chuàng)建,雖然在三級緩存時不是一個完整的Bean,但是已經(jīng)可以被識別了。

下圖是TestService與TestService2的依賴注入圖示?



?

TestService在第一次創(chuàng)建時,發(fā)現(xiàn)需要依賴的TestService2不存在,就先將自己曝光在三級緩存,在TestService2創(chuàng)建時,一二級內(nèi)存都沒有,曝光自己在三級緩存,在依賴屬性有需要的TestService實例,在三級緩存發(fā)現(xiàn),依賴屬性注入成功,將自己存到一級緩存同時清楚二三級緩存,這時候TestService在一級緩存發(fā)現(xiàn)TestService2的依賴Bean,依賴屬性注入成功,將自己存到一級緩存同時清楚二三級緩存

Spring不是所有的循環(huán)依賴都能解決,以下情況:

單例的setter注入 可以解決
單例的代理對象setter注入 不一定能解決
多例的setter注入 不能解決
構(gòu)造器注入(構(gòu)造方法先將自己曝光在三級緩存) 不能解決
DependsOn循環(huán)依賴 不能解決

Spring在三級緩存添加ObjectFactory對象,目的是為了更好對實例對象進行增強,直接用實例對象是行不通的。

二級緩存的作用在上面的圖中沒有體現(xiàn)出來,二級緩存的作用是在有間接循環(huán)依賴時(比如三個Bean之間相互依賴)存在兩次從三級緩存獲取不完整的同一個Bean,因為不完整所以可能會不一樣。這時候就是二級緩存發(fā)揮作用的,在第一次三級緩存取得后就會在其二級緩存保留,下次再獲取時直接在二級緩存,保證了一致性。

原文鏈接:https://blog.csdn.net/l1050188952/article/details/126208238

欄目分類
最近更新