前面說到對象的創建,那么在創建的過程中Spring是怎么又是如何解決循環依賴的呢。前面提到有個三級緩存。就是利用這個來解決循環依賴。打個比方說實例化A的時候,先將A創建(早期對象)放入一個池子中。這個時候雖然屬性沒有賦值,但是容器已經能認識這個是A對象,只是屬性全是null而已。在populateBean方法中對屬性賦值的時候,發現A依賴了B,那么就先去創建B了,又走一遍bean的創建過程(創建B)。同樣也會把B的早期對象放入緩存中。當B又走到populateBean方法的時候,發現依賴了A,好吧,我們又去創建A唄,但是這個時候去創建A,發現我們在緩存能找到A(早期對象)了。就可以把B的A屬性賦值了,這個時候B就初始化完成了。現在回到A調用的populateBean方法中。返回的就是B對象了,對A的B屬性進行賦值就可以了。流程如下:

這就是Spring IOC如何解決循環依賴的原理,但是IOC無法解決兩種循環依賴,一種是非單例對象的,因為非單例對象不會放入緩存的。每次都是需要創建。二是通過構造器注入,也無法解決。從上面的流程可以看出,調用構造器創建實例是在createBeanInstance方法,而解決循環依賴是在populateBean這個方法中,執行順序也決定了無法解決該種循環依賴。對於這種,如果喜歡使用lombok的@RequiredArgsConstructor注解的小伙伴就需要注意了,這個注解會生成一個帶所有屬性的構造方法。通過idea直接點開對應的class文件就可以看不看這個構造方法了。
問題:解決循環依賴一定要三級緩存嘛?
關鍵代碼位置:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory
首先我們的一級緩存是單例緩存池(singletonObjects),二級緩存是早期對象(earlySingletonObjects),三級緩存是一個包裹對象ObjectFactory(registeredSingletons),通過getObject獲取到早期對象。
從上面的流程來看,實際上二級緩存已經可以解決循環依賴了,那么為什么Spring還要包裹出來一個三級緩存呢?
從Spring Ioc(3)---bean的實例化中的源碼分析我們可以看到調用三級緩存中的getObject方法實際上是調用的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference這個方法。

那么我就看看這個方法里面干了些什么事情:
執行SmartInstantiationAwareBeanPostProcessor這個類型處理器的getEarlyBeanReference方法。

斷點調試,發現Spring原生中實現了這個接口的類org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter,實際上什么事情都沒有干,直接返回了,

但是如果是AOP要切的對象,會在這里生成代理對象返回,AOP流程:Spring aop(1)--- 尋找切面和代理對象執行流程源碼分析

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference。
所以說第三級緩存其實是為了解決代理對象之間的循環依賴。
