文章目录
结论
只有单例模式下的循环依赖才可以,其他模式会报错。
对循环依赖的简单介绍
A依赖B、B依赖A 形成一个依赖环。spring
的解决方案是,实例化A,之后将A封装到一个ObjectFactory
对象中存储。对A进行属性填充的时候,发现有B需要实例化,则去实例化B,实例化B的时候也会将B封装到一个ObjectFactory
对象中存储。B实例化完之后,会去填充B的属性,这是发现有A属性需要填充,这是不再会去创建A而是从封装了A对象的ObjectFactory
中直接取。从而完成B的属性填充,继而完成了A的属性填充。
源码分析
本次源码分析中案例是UrlService
和UrlService2
相互依赖。系统首先实例化UrlService
,再实例化UrlService2
。仔细观察截图可见下面的截图有两次处理依赖处理。我们的本篇的原码也是以下图的方法压栈顺序依次分析。分析者需要有对spring的源码整体有一定的把握,可以参考我的另外两篇文章
。
下面进行代码分析篇。
#AbstractBeanFactory
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...省略
// 创建bean的入口
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
return (T) bean;
}
# DefaultSingletonBeanRegistry
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
//省略
singletonObject = singletonFactory.getObject(); //实际进入上个代码块的createBean(beanName, mbd, args)方法
//省略
}
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[