@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