版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/w1lgy/article/details/81086171
最近重新再看spring的内容的時候有個疑問:當spring對象對象存在互相依賴注入的時候,會不會造成死循環,如果不會spring是怎麼解決的?帶着這個疑問我自己在eclipse試了一下,發現是能正常運作的,那麼spring是怎麼做到的呢,帶着疑問我百度了一下,查到一篇部落格可供大家參考:
https://blog.csdn.net/u012410733/article/details/61062858 。但是這篇部落格并不能完全解決的疑問,于是我又把問題發給了線上教育訓練的導師和教育訓練的會員群上,經過老師的解讀加上我查閱資料,做出以下總結:一、Spring 循環依賴需要滿足三個條件:
1、setter 注入(構造器注入不能循環依賴)
2、singleton bean(非單例 bean 不支援)
3、AbstractAutowireCapableBeanFactory#allowCircularReferences 這個 boolean 屬性控制是否可以循環,預設為 true。
二、Spring 建立對象分為三個過程:
1、建立對象執行個體 Object obj = new Object() 或者 Object obj = new Object(xxx);
AbstractAutowireCapableBeanFactory#createBeanInstance
2、依賴注入: obj.setXxx(xxx) {多個屬性就是 foreach}
AbstractAutowireCapableBeanFactory#populateBean
3、Spring bean 擴充方法:init-method,BeanPostProcess,XXXAware 擴充
AbstractAutowireCapableBeanFactory#initializeBean
實作原理:
我們知道在循環依賴當中其實就是多個 bean 調用 BeanFactory#getBean
具體實作在 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
而這個方在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean 方法前。
首先來看一下 AbstractBeanFactory#doGetBean
在進入 doGetBean 方法時就會從緩存裡面拿 beanName 對應的對象。
其實中就包含建立的 ObjectFactory
總結
互相依賴:A 依賴 B, B 依賴 A
當 A 建立的時候,會把 A 對應的 ObjectFactory 放在緩存中,當依賴注入的時候發現了 B 對象,調用 getBean() 方法擷取 B 對象, 然後建立 B 對象,會把 B 對應的 ObjectFactory 放在緩存中。
此時 B 依賴 A ,然後再調用 getBean 擷取 A 對象, 此時調用 AbstractBeanFactory#doGetBean 從緩存中擷取到 A 對應的 ObjectFactory。
這樣就避免了死循環,然後再建立成功之後删除 ObjectFactory 完成依賴注入。
思路:中間對象去解決循環依賴。