個人直覺告訴我循環依賴一定會致使死鎖。 可是Spring支持循環依賴,因此本文就來探討Spring底層是如何實現循環依賴的。java
本文Spring的依賴注入經過註解形式實現 A.java緩存
class A { @Autowired private B b; }
B.javapost
class B { @Autowired private A a; }
第一眼會感受這依賴不是無限循環下去了嗎? 可是想一想的確是可行的。this
首先須要瞭解SpringBeanFactory中的一些容器:code
緩存 | 用途 |
---|---|
singletonObjects | 用於存放徹底初始化好的 bean,從該緩存中取出的 bean 能夠直接使用 |
earlySingletonObjects | 存放原始的 bean 對象(還沒有填充屬性),用於解決循環依賴 |
singletonFactories | 存放 bean 工廠對象,用於解決循環依賴 |
singletonsCurrentlyInCreation | 存放當前正在建立的bean |
循環依賴流程以下:對象
DefaultSingletonBeanRegistry.java
中getSingleton(String beanName, boolean allowEarlyReference)方法:rem
protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); // 判斷bean是否正在建立過程當中 // 好比A正在初始化過程當中須要依賴注入B參數 // Spring就須要區建立B實例,這時候A就在初始化過程當中 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); // earlySingletonObject用來解決循環依賴 this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return (singletonObject != NULL_OBJECT ? singletonObject : null); }