循环依赖其实就是循环引用,也就是两个或者两个以上的bean互相持有对方,最终形成闭环。A 依赖 B,B 又依赖 A,它们之间形成了循环依赖。或者是 A 依赖 B,B 依赖 C,C 又依赖 A。它们之间的依赖关系如下:
注意,这里不是函数的循环调用,是对象的相互依赖关系。循环调用其实就是一个死循环,除非有终结条件。
其中,构造器的循环依赖问题是无法解决,只能拋出BeanCurrentlyInCreationException异常,在解决属性循环依赖时,spring采用的是提前暴露对象的方法。
检测循环依赖相对比较容易,Bean在创建的时候可以给该Bean打标,如果递归调用回来发现正在创建中的话,即说明了循环依赖了。
/** Cache of singleton objects: bean name to bean instance. */
//一级缓存:单例对象缓存池,beanName->Bean,其中存储的就是实例化,属性赋值成功之后的单例对象
private final Map singletOnObjects= new ConcurrentHashMap(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
//三级缓存:单例工厂的缓存,beanName->ObjectFactory,添加进去的时候实例还未具备属性
// 用于保存beanName和创建bean的工厂之间的关系map,单例Bean在创建之初过早的暴露出去的Factory,
// 为什么采用工厂方式,是因为有些Bean是需要被代理的,总不能把代理前的暴露出去那就毫无意义了
private final Map> singletOnFactories= new HashMap(16);
/** Cache of early singleton objects: bean name to bean instance. */
//二级缓存:早期的单例对象,beanName->Bean,其中存储的是实例化之后,属性未赋值的单例对象
// 执行了工厂方法生产出来的Bean,bean被放进去之后,
// 那么当bean在创建过程中,就可以通过getBean方法获取到
private final Map earlySingletOnObjects= new HashMap(16);
根据缓存变量上面的注释,大家应该能大致了解他们的用途。我这里简单说明一下吧:
缓存 | 用途 |
---|---|
singletonObjects | 用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用。 |
earlySingletonObjects | 提前曝光的单例cache,存放原始的 bean 对象(尚未填 充属性),用于解决循环依赖。 |
singletonFactories | 存放 bean 工厂对象,用于解决循环依赖。 |
对Bean的创建最为核心三个方法解释如下:
从对单例Bean的初始化可以看出,循环依赖主要发生在第二步(populateBean),也就是field属性注入的处理。
Spring的循环依赖的理论依据基于Java的引用传递,当获得对象的引用时,对象的属性是可以延后设置的。(但是构造器必须是在获取引用之前)。
由refresh()为入口切入, 这里只分析单例bean创建流程:
1、AbstractBeanFactory.getBean为入口 并委托 AbstractBeanFactory.doGetBean创建。
2、AbstractBeanFactory.doGetBean 会首先从AbstractBeanFactory.getSingleton中获取缓存的bean对象, 如果不存在则调用抽象方法createBean, 即子类实现的AbstractAutowireCapableBeanFactory.createBean方法。
3、AbstractAutowireCapableBeanFactory.createBean方法触发doCreateBean依次调用以下方法实现bean创建过程:
1、AbstractAutowireCapableBeanFactory.autowireConstructor使用构造函数进行实例化。
2、最终调用 ConstructorResolver.autowireConstructor 和 ConstructorResolver.resolveConstructorArguments 进行实例化已经解析构造参数。
3、调用BeanDefinitionValueResolver.resolveValueIfNecessary 和 BeanDefinitionValueResolver.resolveReference 模版类解析构造参数。
步骤配上代码:
@Override
public Object getBean(String name) throws BeansException {
// 获取name对应的bean实例,如果不存在,则创建一个
return doGetBean(name, null, null, false);
}
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 1.解析beanName,主要是解析别名、去掉FactoryBean的前缀“&”
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 2.尝试从缓存中获取beanName对应的实例
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 3.如果beanName的实例存在于缓存中
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 3.1 返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 4.scope为prototype的循环依赖校验:如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常。
// 例子:如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 5.获取parentBeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
// 5.1 如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 5.2 将别名解析成真正的beanName
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
// 5.3 尝试在parentBeanFactory中获取bean对象实例
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
// 6.如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存
markBeanAsCreated(beanName);
}
try {
// 7.根据beanName重新获取MergedBeanDefinition(步骤6将MergedBeanDefinition删除了,这边获取一个新的)
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 7.1 检查MergedBeanDefinition
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 8.拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 8.1 遍历当前bean依赖的bean名称集合
for (String dep : dependsOn) {
// 8.2 检查dep是否依赖于beanName,即检查是否存在循环依赖
if (isDependent(beanName, dep)) {
// 8.3 如果是循环依赖则抛异常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 8.4 将dep和beanName的依赖关系注册到缓存中
registerDependentBean(dep, beanName);
try {
// 8.5 获取dep对应的bean实例,如果dep还没有创建bean实例,则创建dep的bean实例
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
// 9.针对不同的scope进行bean的创建
if (mbd.isSingleton()) {
// 9.1 scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
sharedInstance = getSingleton(beanName, () -> {
try {
// 9.1.1 创建Bean实例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
// 9.1.2 返回beanName对应的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
// 9.2 scope为prototype的bean创建
Object prototypeInstance = null;
try {
// 9.2.1 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
// 9.2.2 创建Bean实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 9.2.3 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
afterPrototypeCreation(beanName);
}
// 9.2.4 返回beanName对应的实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 9.3 其他scope的bean创建,可能是request之类的
// 9.3.1 根据scopeName,从缓存拿到scope实例
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 9.3.2 其他scope的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
Object scopedInstance = scope.get(beanName, () -> {
// 9.3.3 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
try {
// 9.3.4 创建bean实例
return createBean(beanName, mbd, args);
}
finally {
// 9.3.5 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
afterPrototypeCreation(beanName);
}
});
// 9.3.6 返回beanName对应的实例对象
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
// 如果创建bean实例过程中出现异常,则将beanName从alreadyCreated缓存中移除
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
// 10.检查所需类型是否与实际的bean对象的类型匹配
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 10.1 类型不对,则尝试转换bean类型
T cOnvertedBean= getTypeConverter().convertIfNecessary(bean, requiredType);
if (cOnvertedBean== null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
// 11.返回创建出来的bean实例对象
return (T) bean;
}
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** Cache of singleton objects: bean name to bean instance. */
//一级缓存:单例对象缓存池,beanName->Bean,其中存储的就是实例化,属性赋值成功之后的单例对象
private final Map singletOnObjects= new ConcurrentHashMap(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
//三级缓存:单例工厂的缓存,beanName->ObjectFactory,添加进去的时候实例还未具备属性
// 用于保存beanName和创建bean的工厂之间的关系map,单例Bean在创建之初过早的暴露出去的Factory,
// 为什么采用工厂方式,是因为有些Bean是需要被代理的,总不能把代理前的暴露出去那就毫无意义了
private final Map> singletOnFactories= new HashMap(16);
/** Cache of early singleton objects: bean name to bean instance. */
//二级缓存:早期的单例对象,beanName->Bean,其中存储的是实例化之后,属性未赋值的单例对象
// 执行了工厂方法生产出来的Bean,bean被放进去之后,
// 那么当bean在创建过程中,就可以通过getBean方法获取到
private final Map earlySingletOnObjects= new HashMap(16);
/** Names of beans that are currently in creation. */
//三级缓存是用来解决循环依赖,而这个缓存就是用来检测是否存在循环依赖的
private final Set singletOnsCurrentlyInCreation=
Collections.newSetFromMap(new ConcurrentHashMap(16));
/** Names of beans currently excluded from in creation checks. */
//直接缓存当前不能加载的bean
private final Set inCreatiOnCheckExclusions=
Collections.newSetFromMap(new ConcurrentHashMap(16));
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1.从单例对象缓存中获取beanName对应的单例对象
Object singletOnObject= this.singletonObjects.get(beanName);
// 2.如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
if (singletOnObject== null && isSingletonCurrentlyInCreation(beanName)) {
//尝试给一级缓存对象加锁,因为接下来就要对缓存对象操作了
synchronized (this.singletonObjects) {
// 4.从早期单例对象缓存中获取单例对象(之所称成为早期单例对象,是因为earlySingletonObjects里
// 的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
//尝试从二级缓存earlySingletonObjects这个存储还没进行属性添加操作的Bean实例缓存中获取
singletOnObject= this.earlySingletonObjects.get(beanName);
// 5.如果在早期单例对象缓存中也没有,并且允许创建早期单例对象引用
//如果还没有获取到并且第二个参数为true,为true则表示bean允许被循环引用
if (singletOnObject== null && allowEarlyReference) {
// 6.从单例工厂缓存中获取beanName的单例工厂
//从三级缓存singletonFactories这个ObjectFactory实例的缓存里尝试获取创建此Bean的单例工厂实例
ObjectFactory> singletOnFactory= this.singletonFactories.get(beanName);
//如果获取到工厂实例
if (singletonFactory != null) {
// 7.如果存在单例对象工厂,则通过工厂创建一个单例对象
singletOnObject= singletonFactory.getObject();
// 8.将通过单例对象工厂创建的单例对象,放到早期单例对象缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
// 9.移除该beanName对应的单例对象工厂,因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了,
// 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂
this.singletonFactories.remove(beanName);
}
}
}
}
// 10.返回单例对象
return singletonObject;
}
}
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
//判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载。
Class> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 如果resolvedClass存在,并且mdb的beanClass类型不是Class,并且mdb的beanClass不为空(则代表beanClass存的是Class的name),
// 则使用mdb深拷贝一个新的RootBeanDefinition副本,并且将解析的Class赋值给拷贝的RootBeanDefinition副本的beanClass属性,
// 该拷贝副本取代mdb用于后续的操作
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 2.验证及准备覆盖的方法(对override属性进行标记及验证)
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 3.实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例,达到“短路”效果
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 4.如果bean不为空,则会跳过Spring默认的实例化过程,直接使用返回的bean
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 5.创建Bean实例(真正创建Bean的方法)
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
// 6.返回创建的Bean实例
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
}
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 1.新建Bean包装类
BeanWrapper instanceWrapper = null;
//如果RootBeanDefinition是单例的,则移除未完成的FactoryBean实例的缓存
if (mbd.isSingleton()) {
// 2.如果是FactoryBean,则需要先移除未完成的FactoryBean实例的缓存
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 3.根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrapper
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 4.拿到创建好的Bean实例
final Object bean = instanceWrapper.getWrappedInstance();
// 5.拿到Bean实例的类型
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 6.应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition,
// Autowired注解、Value注解正是通过此方法实现注入类型的预解析
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 7.判断是否需要提早曝光实例:单例 && 允许循环依赖 && 当前bean正在创建中
boolean earlySingletOnExposure= (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 8.提前曝光beanName的ObjectFactory,用于解决循环引用
// 8.1 应用后置处理器SmartInstantiationAwareBeanPostProcessor,允许返回指定bean的早期引用,若没有则直接返回bean
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
// 初始化bean实例。
Object exposedObject = bean;
try {
// 9.对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例
populateBean(beanName, mbd, instanceWrapper);
// 10.对bean进行初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
// 11.如果允许提前曝光实例,则进行循环依赖检查
Object earlySingletOnReference= getSingleton(beanName, false);
// 11.1 earlySingletonReference只有在当前解析的bean存在循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
if (exposedObject == bean) {
// 11.2 如果exposedObject没有在initializeBean方法中被增强,则不影响之前的循环引用
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 11.3 如果exposedObject在initializeBean方法中被增强 && 不允许在循环引用的情况下使用注入原始bean实例
// && 当前bean有被其他bean依赖
// 11.4 拿到依赖当前bean的所有bean的beanName数组
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 11.5 尝试移除这些bean的实例,因为这些bean依赖的bean已经被增强了,他们依赖的bean相当于脏数据
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
// 11.6 移除失败的添加到 actualDependentBeans
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
// 11.7 如果存在移除失败的,则抛出异常,因为存在bean依赖了“脏数据”
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// 12.注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
// 13.完成创建并返回
return exposedObject;
}
}
1、Bean A的首次创建,会调用doCreateBean方法,在doCreateBean方法里会经过层层包装,在调用createBeanInstance方法之后,会创建一个没有任何属性的Bean的实例,并返回该实例的包装类BeanWrapper。
2、在调用addSingletonFactory方法之前,将Bean A实例放入ObjectFactory里面,然后调用addSingletonFactory方法将Bean A相关的ObjectFactory实例添加到三级缓存singletonFactories中,此时只有三级缓存中保存了该Bean 对应的ObjectFactory实例。
3、随后调用populateBean方法给属性赋值,由于Bean A直接依赖于Bean B,所以在populateBean方法中会再次调用getBean方法在容器里去尝试获取Bean B的实例。此时由于Bean B实例还没有创建出来,因此又会递归的调用到doCreateBean方法,在doCreateBean方法中调用createBeanInstance方法创建出Bean B实例,并将其对应的ObjectFactory方法放入到三级缓存中,此时三级缓存中就保存了循环依赖的Bean A和B的各自的ObjectFactory实例。
4、随后在Bean B实例又会调用populateBean方法给其属性赋值。此时由于Bean B又依赖于Bean A,所以在populateBean方法中又会调用getBean方法尝试获取Bean A实例。
5、此时会调用AbstractBeanFactory中的doGetBean方法,doGetBean方法会尝试调用getSingleton方法从三级缓存中去获取Bean A的实例。而在一级缓存singletonObjects和二级缓存earlySingletonObjects中都获取不到,而在三级缓存singletonFactories中获取到Bean A实例对应的ObjectFactory实例,调用其getObject方法获取Bean A实例。通过getObject方法获取到了Bean A实例之后,将A实例放入到二级缓存中,同时清空三级缓存中的实例,并将Bean A实例返回。
6、由于Bean A实例实在Bean B实例执行populateBean方法的时候获取到了,此时已经将Bean A实例注入到了Bean B实例中,此时Bean B会执行完doCreateBean的剩余方法,并返回一个初始化完整的Bean实例。
7、由于doCreateBean方法是通过doGetBean方法调用的,所以会将完整的Bean B实例逐层返回到doGetBean方法(AbstractBeanFactory)中。而AbstractBeanFactory的getSingleton方法在执行singletOnObject= singletonFactory.getObject()代码时,才正式执行createBean方法。
8、在getSingleton方法中会最终执行addSingleton(beanName, singletonObject)方法,在addSingleton方法中会将Bean B实例添加进一级缓存singletonObjects中,并将Bean B实例从二级缓存(earlySingletonObjects)和三级缓存(singletonFactories)中清除,此时表明彻底完成了Bean B实例的创建,随后将完整的Bean B实例返回。
9、Bean B实例的创建是由于Bean A实例调用populateBean方法触发的,所以此时,又会回到创建Bean A时的populateBean方法中,此时Bean A就赋值上了完整的Bean B,在Bean A实例完整创建之后又会逐层返回到doGetBean方法中,之后又会调用addSingleton将Bean A实例放入到一级缓存中,同时清除二级和三级缓存中的Bean A实例。
// 4.scope为prototype的循环依赖校验:如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常。
// 例子:如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
单例Setter注入循环依赖(singleton)问题的解决,主要是单例的三级缓存,三级缓存除了解决循环依赖之外,还解决了保持单例唯一性的问题,因为从缓存中取出来的Bean实例是要保证唯一的,所以三级缓存支持不了prototype,因为prototype的Bean实例不唯一。
正式因为没有三级缓存的支持,才导致prototype不支持循环依赖。
由于单例的构造函数注入方式,实在doCreateBean方法中的createBeanInstance方法中完成的,此时还没有三级缓存。在createBeanInstance方法中的autowireConstructor(beanName, mbd, ctors, args)方法中进行Bean的实例化和参数注入,而此时构造函数的实例参数并没有构造出来,所以构造函数的参数实例也会调用getBean方法去创建实例参数,而实例参数又需要之前依赖的实例参数,最后又会递归到autowireConstructor方法,所以导致无限循环。
参考:
https://blog.nowcoder.net/n/2bb528b258b44c7eab1703a52170ef09
https://blog.csdn.net/weixin_30951389/article/details/97471000
https://www.cnblogs.com/liuqing576598117/p/11227007.html