spring解決循環依賴,spring啓動流程圖分享

1.spring解決循環依賴

以例子Husband Wife爲例,一個丈夫只有一位妻子,一位妻子只有一位丈夫,兩個對象相互引用(Husband 類有屬性Wife,Wife類有屬性Husband,兩個類都有setter方法)

畫了個圖

這個流程看着還是比較麻煩的,實際清除明白bean的創建流程就很容易,從圖中可以看出,關鍵是在DefaultSingletonBeanRegistry.singletonFactories這個緩存和DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, true)、DefaultSingletonBeanRegistry.addSingletonFactory(String, ObjectFactory<?>)方法。

IOC有三個主要map緩存

1. DefaultSingletonBeanRegistry.singletonObjects 緩存最終的bean,即IOC的單例對象的容器

2. DefaultSingletonBeanRegistry.singletonFactories 緩存 beanName與ObjectFactory對象,用於解決循環依賴,在DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String)方法內添加

3. DefaultSingletonBeanRegistry.earlySingletonObjects 用於存儲在創建Bean早期時候對創建的原始bean的一個引用,這裏是原始bean(此時bean還沒被注入屬性),一旦bean最終創建好,此引用信息將刪除。作用是爲解決循環依賴而提早暴露出來的實例,用作補充singletonFactories,查找bean是該緩存沒有再查找singletonFactories

spring IOC

解決循環依賴的大體步驟:

husband先實例化,並且將自己提前曝光到singletonFactories中,此時進行填充husband屬性,發現自己依賴對象wife,此時就嘗試去get(wife),發現wife還沒有被create,所以走create流程,wife在初始化第一步的時候發現自己依賴了對象husband,於是嘗試get(husband),嘗試緩存singletonObjects(肯定沒有,因爲husband還沒初始化完全),接着嘗試緩存earlySingletonObjects(也沒有),嘗試緩存singletonFactories,由於husband通過ObjectFactory將自己提前曝光了,所以wife能夠通過ObjectFactory.getObject拿到husband對象(雖然husband還沒有初始化完全),wife拿到husband對象後順利完成了初始化階段(填充wife對象屬性husband),完全初始化之後將自己緩存到singletonObjects中。此時返回husband中,husband此時能拿到wife的對象順利完成自己的屬性填充,最終husband也完成了初始化,緩存到singletonObjects中,而且此時,由於wife拿到了husband的對象引用,所以wife現在hold住的husband對象完成了初始化(對象是引用傳遞)。

 

2.spring IOC啓動流程

本來總結了更加詳細的圖,但是可能只有我自己能看清楚了,就放個簡化的圖

 更加簡化的bean創建圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章