1. 程式人生 > 其它 >Spring如何處理迴圈依賴問題

Spring如何處理迴圈依賴問題

Spring如何處理迴圈依賴問題

什麼是迴圈依賴:

就是多個bean之間相互依賴,形成了一個閉環,比如beanA需要引用BeanB,BeanB需要引用BeanA,形成迴圈關係。一般預設在單例模式中,屬性相互影響的場景。(多個物件之間存在迴圈的引用關係,在初始化過程當中,就會出現“ 先有蛋還是先有雞 ”的問題)

依賴注入的兩種方式:

  1. 構造方法注入【不適合解決迴圈依賴】 構造器迴圈依賴是無法解決的,如果想讓構造器支援迴圈依賴,是不可能的。

  2. set方法注入

spring bean發生迴圈依賴有三種形式:互相依賴、三者之間及其以上的依賴、自我依賴。

如何解決迴圈依賴:

  1. 使用@Lazy註解:解決構造方法造成的迴圈依賴問題

    @Lazy註解: 當@Lazy 放在類上,表示在啟動的時候不會建立bean物件,當使用的時候才會建立; 當@Lazy 放在@Bean註解的方法上,表示在啟動的時候不會建立bean物件,當使用的時候才會建立; 當@Lazy 放在@Autowired註解的屬性上, 並不會直接給屬性賦上真正的值,只是會賦值一個代理物件,當真正使用到這個屬性的時候,才回去容器中找到一個符合的物件。在使用的時候,也會先執行代理物件的邏輯,然後再是真正bean物件的邏輯; 使用場景:迴圈依賴的時候可以在迴圈依賴的物件加上@Lazy註解; 寫在方法或者方法引數前面上,效果和寫在屬性上、一樣的,開始注入的只是代理物件,當真正呼叫的時候才會呼叫對應物件的邏輯 寫在構造方法或者構造方法引數前面上,同上。

     

  2. 使用三級快取

    利用快取機制解決迴圈依賴問題,spring設計了三級快取解決迴圈依賴的問題,分別是一級快取:singletonObjects;二級快取:earlySingletonObjects;三級快取:singletonFactories;

    一級快取:singletonObjects,存放初始化後的單例物件;

    二級快取:earlySingletonObjects,存放例項化,未完成初始化的單例物件(未完成屬性注入的物件);

    三級快取:singletonFactories,存放ObjectFactory物件(代理物件);

     

    三級快取之間逐級取,流程如下

    1、getBean()獲取例項,Spring首先從一級快取singletonObjects中獲取;

    2、如果獲取不到,就從二級快取earlySingletonObjects中獲取,如果還是獲取不到意味著bean沒有例項化;

    3、這時singletonFactories通過getObject()獲取,就從三級快取singletonFactory.getObject()(三級快取)獲取;(代理也是從三級快取生產的)

    4、如果從三級快取中獲取到就從singletonFactories中移除,並放入earlySingletonObjects中。其實也就是從三級快取移動到了二級快取;

    5、這個bean存在會等待下一次輪尋的時候去賦值(解析@Autowared,@Resource)註解等,屬性賦值完成後,將bean存入一級快取;

    解決迴圈依賴簡單的流程圖:

     

轉載至:

https://www.cnblogs.com/huangtiing/p/16743815.html

https://blog.csdn.net/DQWERww/article/details/126128229

https://blog.csdn.net/yaoyaochengxian/article/details/118636958