1. 程式人生 > 其它 >Spring bean建立之迴圈依賴與三級快取

Spring bean建立之迴圈依賴與三級快取

Spring bean建立之迴圈依賴與三級快取

迴圈依賴

多個物件之間互相引用形成環

如果使用普通new方法建立,物件之間會迴圈建立導致OOM

三級快取
  • 一級快取:singletonObjects
  • 二級快取:earlySingletonObjects
  • 三級快取:singletonFactories

在建立物件時會按照:一級--->二級--->三級的順序嘗試獲取物件

bean的建立

對於ClassPathXmlApplicationContext獲取bean物件,前置有一系列方法初始化容器、定義BeanFactoryPostProcess、國際化、多播器等的準備工作。

核心物件建立物件方法:

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

堆疊資訊:

之後將會迴圈遍歷需要建立bean物件的列表,呼叫getBean方法

嘗試從三級快取中獲取:

獲取不到,只能建立物件:

將會呼叫lambda表示式中的createBean進行物件的建立

到此物件已經例項化完成,需要進行初始化,不過在呼叫populateBeanff初始化前,將呼叫addSingletonFactory方法將包含自身例項的objectFactory放入第三級快取中。

具體的實現方法:

為了解決依賴的物件不存在的問題,同樣是依靠getBean方法解決

不過這一次,在第三級快取中可以獲取到迴圈依賴的物件(假設是兩個物件之間迴圈依賴,開始建立的是A物件,目前建立的是B物件,此時B物件可以從第三級快取中獲取到例項化的A物件,直接裝配到B物件中)

此時獲取到只例項化的A物件後,將第三級快取中的A物件移除,放到二級快取中,值得注意的是B物件在初始化前也會將自己放入三級快取中,由於自身的依賴已經解決,B物件在getSingleton方法返回前又會將自己的從三級快取中刪除放到一級快取中。

至此B物件已經初始化完成,只需將屬性注入到A中即可,而A物件被初始化完成之後也會將自己從二三級快取中刪除,放入到一級快取中,至此A物件建立完成。

在for迴圈遍歷下一個需要建立的Bean時,會直接從快取中獲取,不需要再例項化、初始化。

整個過程的堆疊資訊:

流程圖: