1. 前序
循環依賴就是N個類循環嵌套引用,Spring處理循環依賴問題有三種情況:
- 構造器循環依賴:這種情況Spring無法處理,直接拋出BeanCurrentlyInCreationException異常
- 單例模式下的setter循環依賴:通過“三級緩存”處理循環依賴。
- 非單例循環依賴:無法處理
2. 構造器循環依賴
bean的創建,首先執行類的構造器,將當前正在創建的bean記錄在緩存中,singletonsCurrentlylnCreation.add(beanName)。在創建過程中一直存在在緩存中,如果在創建bean過程中發現自己已經在創建bean池中,將拋出BeanCurrentlyInCreationException異常表示循環依賴,對於創建完畢的bean將從創建bean池中移除。
3. 單例模式下的setter循環依賴

spring容器解決單例模式下setter循環依賴,使用了多級緩存:
1. singletonObjects:緩存生成的單例對象
2. singletonFactories:緩存提前暴露的生成半成品bean的ObjectFactory
3. earlySingletonObjects:存儲由ObjectFactory生成的半成品bean
對於A->B,B->A的情況,spring容器在生成A的過程中,首先暴露ObjectFactory到緩存singletonFactories,然後在容器中查找依賴B。容器生成依賴B,使用深度遞歸調用,調用getBean(name)。在生成B的過程中依賴A,在容器中查找A,首先在緩存中查找。在緩存singletonFactories中獲取提前暴露的生成A的ObjectFactory,生成返回A的引用,B對象生成完成返回,繼而A對象生成完成。
spring容器使用提前暴露半生成bean、多級緩存機制,實現解決單例模式下setter的循環依賴問題。
4. 非單例循環依賴
對弈prototype作用域的bean,spring容器無法完成依賴注入,因爲spring容器不進行緩存prototype作用域的bean,因此無法提前暴露一個創建中的bean