@Component
class A{
@Resource
private B b;
}
@Component
class B{
@Resource
private A a;
}
Spring在創建單例bean時是如何解決循環依賴?
注:在多例模式下,會拋出BeanCurrentlyInCreationException(beanName);
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** Set of registered singletons, containing the bean names in registration order. */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
/** Names of beans that are currently in creation. */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
創建過程:
- getSingleton(),A
- doCreateBean(),提前暴露,
earlySingletonExplore=true
;調用addSingletonFactories()
將A工廠添加到singletonFactories
中 - populateBean():給A屬性賦值,發現B
- getSingleton(),B
- doCreateBean(),提前暴露,
earlySingletonExplore=true
;調用addSingletonFactories()
將B工廠添加到singletonFactories
中 - populateBean():給B屬性賦值,發現A
- getSingleton(),A,此時根據集合
singletonsCurrentlyInCreation
發現A已經在創建過程中,則從A工廠產出一個early-A
添加到earlySingletonObjects
,並且將singletonFactories
中A工廠移除 - 通過addSingleton()將
earlySingletonObjects
中的early-A
填充到B中 - 將B添加到
singletonObjects
中,此時A也完成創建,將A也添加到singletonObjects