中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么理解Spring源碼循環依賴

發布時間:2021-11-02 17:44:59 來源:億速云 閱讀:149 作者:iii 欄目:web開發

這篇文章主要講解了“怎么理解Spring源碼循環依賴”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么理解Spring源碼循環依賴”吧!

Spring是怎么去解決循環依賴的

1.什么是循環依賴

這個詞,阿粉聽到的時候,肯定和大家的反應一樣的,循環,依賴,那是不是 A 引用了 B ,而此時 B  引用了 C,而 C 呢又引用了A,于是一個三角戀的關系出現了。

怎么理解Spring源碼循環依賴

那么用代碼來表示的話,是怎么表示的呢?

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;     } }

怎么理解Spring源碼循環依賴

2.循環依賴會出現什么問題

在阿粉的印象中,循環依賴最直接的問題就是會出現在對象的實例化上面,創建對象的時候,如果在Spring的配置中加入這種 A 依賴  B ,B 依賴 C,C 依賴 A 的話,那么最終創建 A 的實例對象的時候,會出現錯誤。

而如果這種循環調用的依賴不去終結掉他的話,那么就相當于一個死循環,就像阿粉前幾天的在維護那個  “十六年”之前的項目的時候,各種內存溢出,表示內心很壓抑呀。

而 Spring 中也將循環依賴的處理分成了不同的幾種情況,阿粉帶大家來看一下吧。

3.Spring循環依賴處理一  (構造器循環依賴)

構造器循環依賴的意思就是說,通過構造及注入構成的循環依賴,而這種依賴的話,是沒有辦法解決的,如果你敢強行依賴,不要意思,出現了你久違的異常  BeanCurrentlyInCreationException 出現這個異常的時候,就是表示循環依賴的問題。

相信大家出現異常的時候,在看不懂為什么的時候,第一時間,復制異常信息,放在百度,或者Google上面查詢一下,BeanCurrentlyInCreationException  放在百度上,一目了然。

而在 Spring 的配置文件中,如果這么配置 A ,B ,C 的循環依賴的時候,在創建 A 的時候,發現,構造器需要 B 類,然后去創建 B ,而創建  B 的時候,發現又需要 C ,然后去創建 C ,創建的時候發現,竟然需要 A ,于是又掉頭回去了,于是就形成了一個閉環,沒有辦法創建。

<beans>    <bean id="ClassTestA" class="com.yldlsy.ClassTestA" >         <constructor-arg index="0" ref="ClassTestB" />   </bean>    <bean id="ClassTestB" class="com.yldlsy.ClassTestB" >         <constructor-arg index="0" ref="ClassTestC" />   </bean>    <bean id="ClassTestC" class="com.yldlsy.ClassTestC" >          <constructor-arg index="0" ref="ClassTestA" />   </bean> </beans>

而在這種情況下,Spring實例化bean是通過ApplicationContext.getBean()方法來進行的。如果要獲取的對象依賴了另一個對象,那么其首先會創建當前對象,然后通過遞歸的調用ApplicationContext.getBean()方法來獲取所依賴的對象,最后將獲取到的對象注入到當前對象中。而和剛才阿粉說的一樣,創建了閉環,所以就沒有辦法創建了。

4.Spring循環依賴處理二(setter循環依賴)

setter循環注入是指通過setter注入方式構成的循環依賴。而這種方式,是Spring可以進行解決的。

而對于這種使用setter注入造成的依賴是通過Spring容器來提前暴露剛完成的構造注入器的bean來完成的,但是這時候還沒有完成其他的步驟的時候。

這個時候我們就需要提前暴露出來一個單例的工廠方法,讓其他的bean來引用這個bean,

addSingletonFactory(beanName,new ObjectFactory(){     public Object getObject() throws BeanException{         return getEarlyBeanReference(beanName,mbd,bean)     } })
  • Spring在創建 A 的時候,根據無參構造來創建 A,并且暴露出 ObjectFactory 用來返回一個提前暴露好的 bean  然后再進行setter來注入,

同理的B和C都是這個樣子的,這個時候就能完成setter注入了。

5.Spring循環依賴處理三(作用域循環依賴)

阿粉帶大家看一下這個配置方式

<bean id="ClassTestA" class="com.yldlsy.ClassTestA" scope="singleton" >         <property name="ClassTestB" ref="ClassTestB" />     </bean>     <bean id="ClassTestA" class="com.yldlsy.ClassTestA" scope="singleton" >             <property name="ClassTestB" ref="ClassTestB" />      </bean>      <bean id="ClassTestA" class="com.yldlsy.ClassTestA" scope="singleton" >              <property name="ClassTestB" ref="ClassTestB" />       </bean>

而對于  “singleton”作用域的話,他是可以通過“setAllowCircularReference(false)”這種方式來進制循環依賴的。

而且也是有缺陷的,這種方式只能解決單例作用域的bean循環依賴。

而Spring解決循環依賴的話,大家肯定會好奇,說是三級緩存,那么請找到你的Spring的源碼

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

感謝各位的閱讀,以上就是“怎么理解Spring源碼循環依賴”的內容了,經過本文的學習后,相信大家對怎么理解Spring源碼循環依賴這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

定结县| 荥经县| 镇远县| 浦城县| 柯坪县| 新宾| 瑞丽市| 乌恰县| 泾阳县| 略阳县| 合阳县| 信宜市| 金坛市| 绥滨县| 岳普湖县| 贵州省| 永和县| 四子王旗| 巍山| 柳林县| 汉源县| 礼泉县| 苗栗县| 调兵山市| 修水县| 新泰市| 瑞昌市| 南康市| 杭州市| 清水县| 巴塘县| 福清市| 巴里| 石城县| 寻甸| 定安县| 揭东县| 馆陶县| 钟山县| 静宁县| 乌拉特前旗|