1. 程式人生 > 其它 >spring原始碼怎麼解決迴圈依賴?

spring原始碼怎麼解決迴圈依賴?

spring原始碼怎麼解決迴圈依賴?

1.資料準備

這裡先建立2個bean,互相注入,看看spring是怎麼解決這個問題的

@Repository
public class BoyFriend {
   @Autowired
   private GirlFriend girlFriend;
}
@Repository
public class GirlFriend {
   @Autowired
   private BoyFriend boyFriend;
}

2.debug分析邏輯

在populateBean打上斷點,可以發現呼叫棧

一步步分析:

1.AnnotationConfigApplicationContext方法的refresh()方法 因為這裡使用的是註解方式配置的容器

2.refresh()的finishBeanFactoryInitialization(beanFactory); 例項化所有的類(懶載入的類除外)

3.finishBeanFactoryInitialization()的beanFactory.preInstantiateSingletons();方法 例項化所有剩餘的(non-lazy-init非延時載入的)單例

4.preInstantiateSingletons()的getBean(boyFriend);方法

5.getBean(boyFriend)的doGetBean方法

6.dogetbean的getSingleton()方法 這裡使用了一個匿名內部類,建立Bean例項物件,並且註冊給所依賴的物件

7.createBean()

8.doCreateBean()

9.doCreateBean()裡的populateBean方法 準備填充bean例項的屬性

現在增加指定條件斷點:beanName.equals("boyFriend")||beanName.equals("girlFriend"),boyfriend先執行來了。


3.具體流程:

1.addSingletonFactory 三級快取裡新增boyfriend

2.populateBean 中 boyfriend 載入 girlfriend addSingletonFactory 三級快取裡新增girlfriend

3.populateBean girlfriend 載入 boyfriend 從三級快取讀取boyfriend 並將其清除,並儲存boyfriend到二級快取

4.至此girlfriend裝配完畢,執行到defaultSingletonBeanRegister裡的getSingleton方法裡的addSingleton方法將裝配有boyfriend的girlfriend例項存入一級快取,並清除二級快取中的girlfriend,清除三級快取中的girlfriend

5.至此boyfriend裝配完畢,執行到defaultSingletonBeanRegister裡的getSingleton方法裡的addSingleton方法將裝配有girlfriend的boyfriend例項存入一級快取,並清除二級快取中的boyfriend,清除三級快取中的boyfriend


4.spring對其他迴圈依賴的情況

1非單例是否支援依賴?

spring不支援多例迴圈依賴,spring有一個bean正在建立的列表,beanname作為標誌,因為名稱相同所以丟擲迴圈依賴異常

2.構造器迴圈依賴?

spring會把正在建立的單例列表儲存起來,當A物件載入的時候,此時儲存A到列表,去載入A依賴的B物件,B物件載入的時候,儲存B到列表 ,再去載入A ,此時spring發現因為A已經在列表上了,所以丟擲迴圈依賴異常,以為這裡沒有三級快取的概念(程式碼還未執行到三級快取處)相當於只有一級快取,所以無法實現迴圈依賴

再勇敢一點,再炙熱一點吧!