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已經在列表上了,所以丟擲迴圈依賴異常,以為這裡沒有三級快取的概念(程式碼還未執行到三級快取處)相當於只有一級快取,所以無法實現迴圈依賴
再勇敢一點,再炙熱一點吧!