Spring如何解决循环依赖

spring如何解决循环依赖

循环依赖是指两个或多个类之间互相引用。在单例且非构造方法注入的情况下,spring是支持循环依赖的。例如有两个类A和B,这两个类都是单例的(spring默认创建的是单例对象,即scope=Singleton),并且这两个类都是通过非构造方法互相引用对方,spring是支持这样的循环依赖的。

通过三级缓存解决循环依赖,三级缓存的作用是为了解决循环依赖

下面通过源码分析为什么spring默认支持单例且非构造方法注入的循环依赖。

从之前关于bean的生命周期的文章中分析可知(感兴趣的可以看一下:Spring bean的生命周期),在AbstractBeanFactory类的getBean和doGetBean方法中获取bean,在doGetBean方法中调用AbstractAutowireCapableBeanFactory类的createBean方法创建bean,在createBean方法中调用了实际创建bean的doCreateBean方法,在doCreateBean方法中依次调用了createBeanInstance、populateBean和initializeBean等方法进行实例化bean、属性注入和初始化bean操作。

在IoC容器启动时,通过创建bean的一系列过程refresh->finishBeanFactoryInitialization->preInstantiateSingletons->getBean->doGetBean->createBean->doCreateBean->createBeanInstance/populateBean/initializeBean来实例化并初始化一个bean,在创建bean的过程中需要调用populateBean方法完成属性注入,循环依赖就是在这个方法中完成的。

调用AbstractBeanFactory类的getBean方法获取bean:

public Object getBean(String name) throws BeansException {
    return this.doGetBean(name, (Class)null, (Object[])null, false);
}


protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
    String beanName = this.transformedBeanName(name);
    //第一次调用getSingleton方法,如果获取到bean,则返回
    Object sharedInstance = this.getSingleton(beanName);
    Object bean;
    if (sharedInstance != null && args == null) {
        //这里省略了日志判断
        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
        if (this.isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
        //这里省略了与循环依赖无关的代码
        try {
            RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
            this.checkMergedBeanDefinition(mbd, beanName, args);
            //这里省略了与循环依赖无关的代码
            if (mbd.isSingleton()) {
	            //第二次调用getSingleton方法
                sharedInstance = this.getSingleton(beanName, () -> {
                    try {
                        return this.createBean(beanName, mbd, args);
                    } catch (BeansException var5) {
                        this.destroySingleton(beanName);
                        throw var5;
                    }
                });
                bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            } 
	        //这里省略了与循环依赖无关的代码
        } catch (BeansException var26) {
            this.cleanupAfterBeanCreationFailure(beanName);
            throw var26;
        }
    }
    //这里省略了与循环依赖无关的代码
}

这里先分析两次调用getSingleton方法,然后再分析createBean方法创建bean的过程。

两次调用的getSingleton方法不是同一个方法,属于方法重载。

1、第一个getSingleton方法

DefaultSingletonBeanRegistry类中的getSingleton(String beanName)方法:

@Nullable
public Object getSingleton(String beanName) {
    return this.getSingleton(beanName, true);
}


@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
        Map var4 = this.singletonObjects;
        synchronized(this.singletonObjects) {
            //1.为什么先从三级缓存earlySingletonObjects中获取bean实例,不是先从二级缓存中获取工厂创建bean实例?
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                //2.为什么要用二级缓存singletonFactories?不用二级缓存可不可以?
                ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    //3.singletonFactory的getObject方法是如何获取bean实例的?
                    singletonObject = singletonFactory.getObject();
                    //4.为什么要将bean实例放到三级缓存中?不用三级缓存earlySingletonObjects可不可以?
                    this.earlySingletonObjects.put(beanName, singletonObject);
	                //存放在三级缓存后,就要把二级缓存中的beanName删除,不能同时存在二级、三级缓存中
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }

    return singletonObject;
}

调用了DefaultSingletonBeanRegistry类的isSingletonCurrentlyInCreation方法:

public boolean isSingletonCurrentlyInCreation(String beanName) {
    return this.singletonsCurrentlyInCreation.contains(beanName);
}

在第一个getSingleton方法中涉及到了与单例bean有关的三个缓存:singletonObjects(一级缓存)、singletonFactories(二级缓存)和earlySingletonObjects(三级缓存)。还有一个Set集合singletonsCurrentlyInCreation,用于存放当前正在创建的bean的名称。将beanName存放到集合singletonsCurrentlyInCreation中是在下面调用第二个getSingleton方法中完成的。

private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
private final Map<String, Object> earlySingletonObjects = new HashMap(16);
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap(16));

一级缓存singletonObjects用于存放已经创建好的具有完整生命周期的bean,key是bean的名称,value是创建好的bean。二级缓存singletonFactories用于存放生成bean的单例工厂,key是bean的名称,value是生成bean的工厂。三级缓存earlySingletonObjects用于存放不具有完整生命周期的半成品的bean,key是bean的名称,value是半成品的bean。

当第一次创建bean,在doGetBean方法中调用第一个getSingleton方法,此时singletonObjects、singletonFactories、earlySingletonObjects以及singletonsCurrentlyInCreation集合中都没有要创建bean的名称,第一个getSingleton方法返回null。接着在doGetBean方法中调用第二个getSingleton方法。

问题及答案

1、为什么先从三级缓存earlySingletonObjects中获取bean实例,不是先从二级缓存中获取工厂创建bean实例?

是为了提升性能,如果三级缓存中有的话,就不用通过二级缓存的singletonFactory创建实例。

2、为什么要用二级缓存singletonFactories?不用二级缓存可不可以?

二级缓存singletonFactories中存放的是beanName对应的singletonFactory,是通过ObjectFactory的匿名内部类的方式创建该工厂的,并重写了getObject方法。在重写的getObject方法中会判断是否需要为当前bean创建代理对象,如果不需要,则直接返回半成品的bean实例,如果需要,则创建并返回代理对象。对于不需要创建代理对象的bean实例来说,确实不需要二级缓存,在暴露singletonFactory放到二级缓存的地方直接将半成品的bean放到三级缓存earlySingletonObjects中即可,循环依赖第二次调用第一个getSingleton方法时能够从三级缓存中获取到bean实例。但是对于需要创建代理对象的bean实例来说,就需要二级缓存保存singletonFactory,通过singletonFactory来创建代理对象。所以二级缓存singletonFactories的作用是为了解决循环依赖中需要创建代理对象的问题的。

3、singletonFactory的getObject方法是如何获取bean实例的?

从二级缓存中获取提前暴露的工厂singletonFactory,这个工厂是在下面第二个getSingleton方法中的doCreateBean方法中添加到二级缓存中的,是通过ObjectFactory的匿名内部类的方式创建该工厂的。通过匿名内部类创建singletonFactory并重写了getObject方法,在getObject方法中调用了getEarlyBeanReference,该方法的作用就是获取bean实例。如果当前beanName对应的bean需要被代理,在getEarlyBeanReference方法中底层就会调用AbstractAutoProxyCreator的getEarlyBeanReference方法创建bean的代理对象,并返回代理对象。如果不需要被AOP代理,则直接返回半成品的bean实例。

4、为什么要将bean实例放到三级缓存中?不用三级缓存earlySingletonObjects可不可以?

通过二级缓存中的singletonFactory创建bean实例(半成品的bean或bean的代理对象)之后,将bean实例存到三级缓存中,是为了循环依赖第二次调用第一个getSingleton方法时能够从三级缓存中获取到bean实例,无需再通过singletonFactory创建bean实例。假如有这样一种场景:三个类A、B、C,A依赖B和C,B依赖A,C依赖A,且需要对A进行AOP代理。每次通过singletonFactory创建bean的代理对象都不一样。如果不用三级缓存earlySingletonObjects,B依赖A时创建了A的代理对象,C依赖A时又创建了A的另一个代理对象,这样在spring容器中存放的A的bean就不是唯一的了,spring容器是不允许单例bean存在多个bean实例的。

2、第二个getSingleton方法

    sharedInstance = this.getSingleton(beanName, () -> {
        try {
            return this.createBean(beanName, mbd, args);
        } catch (BeansException var5) {
            this.destroySingleton(beanName);
            throw var5;
        }
    });

上面这部分代码是在doGetBean方法中调用第二个getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法的地方,由于这里使用了lamda表达式,看起来不好理解,转换成如下格式。

ObjectFactory<?>  singletonFactory = new ObjectFactory(){
	public Object getObject(){
		//其实这是个抽象类,不能实例化,createBean是子类实现的,这里就不关心了
		AbstractBeanFactory abf = new AbstractBeanFactory();
		Object bean = abf.createBean(beanName, mbd, args);
		return bean;
	}
};

getSingleton方法的第二个参数是ObjectFactory,ObjectFactory是一个接口,有一个getObject方法,此处通过匿名内部类实现ObjectFactory接口,并重写了getObject方法,在getObject方法中调用抽象类AbstractBeanFactory的createBean方法创建bean。将beanName和singletonFactory对象传递给getSingleton方法,并在getSingleton方法中调用singletonFactory对象的getObject方法,实际上就是调用createBean方法。

//singletonFactory对象的getObject方法就是在getSingleton中被调用的
sharedInstance = this.getSingleton(beanName,singletonFactory);
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    Map var3 = this.singletonObjects;
    synchronized(this.singletonObjects) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
	        //如果当前单例bean正在被销毁,则抛出异常
            if (this.singletonsCurrentlyInDestruction) {
                throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
            }

            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
            }
            //创建单例bean之前,将bean标记为正在创建,即保存beanName到Set集合中
            this.beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = this.suppressedExceptions == null;
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet();
            }

            try {
	            //此处就是调用上面lambda表达式方法,实际上调用createBean方法创建bean,创建bean的过程中会有属性注入
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            } catch (IllegalStateException var16) {
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    throw var16;
                }
            } catch (BeanCreationException var17) {
                BeanCreationException ex = var17;
                if (recordSuppressedExceptions) {
                    Iterator var8 = this.suppressedExceptions.iterator();

                    while(var8.hasNext()) {
                        Exception suppressedException = (Exception)var8.next();
                        ex.addRelatedCause(suppressedException);
                    }
                }

                throw ex;
            } finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
	            //无论创建单例bean是否成功,都将beanName从Set集合中删除,不是正在被创建
                this.afterSingletonCreation(beanName);
            }
	        //成功创建单例bean之后,将bean保存到一级缓存中,并从二级三级缓存中删除
            if (newSingleton) {
                this.addSingleton(beanName, singletonObject);
            }
        }

        return singletonObject;
    }
}

调用DefaultSingletonBeanRegistry类的beforeSingletonCreation方法:

// 判断singletonsCurrentlyInCreation中是否含有给定的beanName,即判断beanName是否正在被创建
public boolean isSingletonCurrentlyInCreation(String beanName) {
    return this.singletonsCurrentlyInCreation.contains(beanName);
}

// 集合inCreationCheckExclusions中存放的是被排除的bean,程序员可以提供一些bean不被spring初始化,
// 这些bean就存在这个集合中。集合singletonsCurrentlyInCreation中存放正在被创建的bean
protected void beforeSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName);
    }
}

// 创建单例bean之后,将beanName从集合singletonsCurrentlyInCreation中删除
protected void afterSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
}

在第二个getSingleton方法中调用beforeSingletonCreation方法将bean标记为正在创建,即在集合singletonsCurrentlyInCreation中保存当前正在创建的beanName(当第二次调用getBean(beanName)方法获取bean时(如循环依赖),此时集合singletonsCurrentlyInCreation中就包含beanName了,在第一个getSingleton方法中就可以获取到具有完整生命周期的bean或半成品的bean)。然后执行singletonObject = singletonFactory.getObject(),即调用createBean方法创建bean。

3、createBean方法

调用AbstractAutowireCapableBeanFactory类的createBean方法创建bean:

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    //这里省略了与循环依赖无关的代码
    try {
        // 创建bean
        beanInstance = this.doCreateBean(beanName, mbdToUse, args);
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Finished creating instance of bean '" + beanName + "'");
        }

        return beanInstance;
    } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
        throw var7;
    } catch (Throwable var8) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
    }
}

调用AbstractAutowireCapableBeanFactory类的doCreateBean方法创建bean:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
    }

    if (instanceWrapper == null) {
        //推断出构造函数,通过构造函数反射创建bean实例
        instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    }
    //获取不具有完整生命周期的半成品的bean,在下面提前暴露工厂时会用到
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }
    //这里省略了与循环依赖无关的代码
    //如果是单例、允许循环依赖且正在创建中,则提前暴露一个工厂ObjectFactory<?> singletonFactory
    boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
    if (earlySingletonExposure) {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
        }
        //将(beanName,singletonFactory)存到二级缓存singletonFactories中
        this.addSingletonFactory(beanName, () -> {
	        //这个方法很重要,用于获取bean实例,该方法在第一个getSingleton方法中通过二级缓存singletonFactories获取bean实例时被调用。
            //如果当前beanName对应的bean不需要被AOP代理,则直接返回半成品的bean,如果需要被AOP代理,
            //则在该方法中会调用AbstractAutoProxyCreator的getEarlyBeanReference方法创建当前bean的代理对象并返回代理对象。
            return this.getEarlyBeanReference(beanName, mbd, bean);
        });
    }

    Object exposedObject = bean;

    try {
        //属性注入
        this.populateBean(beanName, mbd, instanceWrapper);
        //初始化bean
        exposedObject = this.initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable var18) {
        if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
            throw (BeanCreationException)var18;
        }

        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
    }
    //这里省略了与循环依赖无关的代码
}

在分析populateBean方法完成属性注入之前,先分析一下addSingletonFactory方法。

if (earlySingletonExposure) {
    if (this.logger.isTraceEnabled()) {
        this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
    }
    // 调用DefaultSingletonBeanRegistry类的addSingletonFactory(beanName, singletonFactory)方法
    this.addSingletonFactory(beanName, () -> {
        return this.getEarlyBeanReference(beanName, mbd, bean);
    });
}

在addSingletonFactory方法中使用了lamda表达式,转换成易于理解的方式,先创建ObjectFactory的匿名对象,重写getObject()方法,作为参数传给addSingletonFactory方法,如下所示。

ObjectFactory<?> singletonFactory = new ObjectFactory<?>(){
	public T getObject(){
		// getEarlyBeanReference这个方法很重要,用于获取bean实例。
        // 如果当前beanName对应的bean不需要被AOP代理,则直接返回半成品的bean,
        // 如果需要被AOP代理,则在该方法中会调用AbstractAutoProxyCreator的
        // getEarlyBeanReference方法创建当前bean的代理对象并返回代理对象。
		getEarlyBeanReference(beanName, mbd, bean);
	}
}

addSingletonFactory(beanName,singletonFactory);

singletonFactory.getObject()方法就是返回当前正在实例化的bean或bean的代理对象,该方法在第一个getSingleton方法中通过二级缓存singletonFactories获取bean实例时被调用。

getEarlyBeanReference的源码如下所示:

/**
 * Obtain a reference for early access to the specified bean,
 * typically for the purpose of resolving a circular reference.
 * @param beanName the name of the bean (for error handling purposes)
 * @param mbd the merged bean definition for the bean
 * @param bean the raw bean instance
 * @return the object to expose as bean reference
 */
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
   Object exposedObject = bean;
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
            exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
         }
      }
   }
   return exposedObject;
}

继续看DefaultSingletonBeanRegistry类的addSingletonFactory方法:

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(singletonFactory, "Singleton factory must not be null");
    Map var3 = this.singletonObjects;
    synchronized(this.singletonObjects) {
        //如果一级缓存中包含beanName,说明已经创建一个具有完整生命周期的bean了
        if (!this.singletonObjects.containsKey(beanName)) {
            //将单例工厂对象存放到二级缓存singletonFactories中
            this.singletonFactories.put(beanName, singletonFactory);
            //一级、二级、三级缓存中不能同时存有beanName,只能有一个存放
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }

    }
}

addSingletonFactory方法中将单例工厂对象存放到二级缓存singletonFactories中,是为了循环依赖时在doGetBean方法中再一次调用第一个getSingleton方法服务的

4、populateBean方法

下面接着分析populateBean方法完成属性注入。

调用AbstractAutowireCapableBeanFactory类的populateBean方法完成属性注入:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
    } else {
        //这里省略了与循环依赖无关的代码
        if (continueWithPropertyPopulation) {
            PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
            if (mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
                MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
	            //通过名称注入
                if (mbd.getResolvedAutowireMode() == 1) {
                    this.autowireByName(beanName, mbd, bw, newPvs);
                }
	            //通过类型注入
                if (mbd.getResolvedAutowireMode() == 2) {
                    this.autowireByType(beanName, mbd, bw, newPvs);
                }

                pvs = newPvs;
            }

            boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
            boolean needsDepCheck = mbd.getDependencyCheck() != 0;
            PropertyDescriptor[] filteredPds = null;
            if (hasInstAwareBpps) {
                if (pvs == null) {
                    pvs = mbd.getPropertyValues();
                }

                Iterator var9 = this.getBeanPostProcessors().iterator();

                while(var9.hasNext()) {
                    BeanPostProcessor bp = (BeanPostProcessor)var9.next();
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                        //对于@Autowired或@Resource注解的属性和方法就是在postProcessProperties方法中完成的属性注入
                        PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            if (filteredPds == null) {
                                filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                            }

                            pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                            if (pvsToUse == null) {
                                return;
                            }
                        }

                        pvs = pvsToUse;
                    }
                }
            }

            if (needsDepCheck) {
                if (filteredPds == null) {
                    filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                }

                this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
            }
	        //配置文件中<property>配置的属性是在这个方法中完成的属性注入
            if (pvs != null) {
                this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
            }

        }
    }
}

调用InstantiationAwareBeanPostProcessor接口的postProcessProperties方法,实际调用AutowiredAnnotationBeanPostProcessor类的postProcessProperties方法。

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

    try {
        metadata.inject(bean, beanName, pvs);
        return pvs;
    } catch (BeanCreationException var6) {
        throw var6;
    } catch (Throwable var7) {
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
    }
}

调用InjectionMetadata类的inject方法:

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Collection<InjectionMetadata.InjectedElement> checkedElements = this.checkedElements;
    Collection<InjectionMetadata.InjectedElement> elementsToIterate = checkedElements != null ? checkedElements : this.injectedElements;
    //InjectedElement是InjectionMetadata的抽象静态内部类,下面调用该类的inject方法
    InjectionMetadata.InjectedElement element;
    if (!((Collection)elementsToIterate).isEmpty()) {
        for(Iterator var6 = ((Collection)elementsToIterate).iterator(); var6.hasNext(); element.inject(target, beanName, pvs)) {
            element = (InjectionMetadata.InjectedElement)var6.next();
            if (logger.isTraceEnabled()) {
                logger.trace("Processing injected element of bean '" + beanName + "': " + element);
            }
        }
    }

}

InjectedElement是InjectionMetadata的抽象静态内部类,调用该类的inject方法,实际上是调用具体实现类AutowiredFieldElement或AutowiredMethodElement中的inject方法,这两个具体实现类是AutowiredAnnotationBeanPostProcessor类中的内部类。此处只分析@Autowired注解用在属性上的情况,即调用AutowiredFieldElement类的inject方法。

调用AutowiredFieldElement类的inject方法:

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Field field = (Field)this.member;
    Object value;
    if (this.cached) {
        value = AutowiredAnnotationBeanPostProcessor.this.resolvedCachedArgument(beanName, this.cachedFieldValue);
    } else {
        DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
        desc.setContainingClass(bean.getClass());
        Set<String> autowiredBeanNames = new LinkedHashSet(1);
        Assert.state(AutowiredAnnotationBeanPostProcessor.this.beanFactory != null, "No BeanFactory available");
        TypeConverter typeConverter = AutowiredAnnotationBeanPostProcessor.this.beanFactory.getTypeConverter();
        //在resolveDependency方法中最终会调用BeanFactory的getBean方法获取属性实例
        try {
            // 调用DefaultListableBeanFactory类的resolveDependency方法
            value = AutowiredAnnotationBeanPostProcessor.this.beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
        } catch (BeansException var12) {
            throw new UnsatisfiedDependencyException((String)null, beanName, new InjectionPoint(field), var12);
        }

        // 省略了其他代码
    }
    //上面获取到属性值之后,在这一步通过反射进行属性注入
    if (value != null) {
        ReflectionUtils.makeAccessible(field);
        field.set(bean, value);
    }

}

调用DefaultListableBeanFactory类的resolveDependency方法:

@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    descriptor.initParameterNameDiscovery(this.getParameterNameDiscoverer());
    if (Optional.class == descriptor.getDependencyType()) {
        return this.createOptionalDependency(descriptor, requestingBeanName);
    } else if (ObjectFactory.class != descriptor.getDependencyType() && ObjectProvider.class != descriptor.getDependencyType()) {
        if (javaxInjectProviderClass == descriptor.getDependencyType()) {
            return (new DefaultListableBeanFactory.Jsr330Factory(null)).createDependencyProvider(descriptor, requestingBeanName);
        } else {
            Object result = this.getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
            if (result == null) {
                // 调用DefaultListableBeanFactory类的doResolveDependency方法
                result = this.doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
            }

            return result;
        }
    } else {
        return new DefaultListableBeanFactory.DependencyObjectProvider(descriptor, requestingBeanName);
    }
}

调用DefaultListableBeanFactory类的doResolveDependency方法:

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);

    Object var14;
    try {
        // 省略了其他代码

        if (instanceCandidate instanceof Class) {
		    // 调用DependencyDescriptor类的resolveCandidate方法
            instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
        }

        // 省略了其他代码
    } finally {
        ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
    }

    return var14;
}

调用DependencyDescriptor类的resolveCandidate方法:(此处的beanName是属性的名称

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) throws BeansException {
    return beanFactory.getBean(beanName);
}

调用BeanFactory的getBean方法,实际调用抽象子类AbstractBeanFactory的getBean方法:

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
    return this.doGetBean(name, requiredType, (Object[])null, false);
}

创建待注入的属性实例,最终又回到创建bean的过程,即实例化、属性注入、初始化,如下所示:

getBean->doGetBean->createBean->doCreateBean->createBeanInstance/populateBean/initializeBean。

假设两个类A和B互相依赖对方。Spring IoC容器在创建A类的bean时,在实例化bean之后,需要进行属性注入操作,将B类的bean注入到A类的bean中(此时还不是一个完整的bean,因为还有属性注入和初始化等操作没有完成,只能是一个对象)。调用populateBean方法在向A的bean注入B的bean的过程中,最终会经过一系列创建bean的过程创建B类的bean,在创建B类的bean时,在走到属性注入这一步,发现B类依赖了A类,需要将A的bean注入到B的bean中,这样就形成了循环依赖。

在doCreateBean方法中会调用instanceWrapper=this.createBeanInstance(beanName,mbd,args);方法创建bean实例,在该方法中会推断出构造函数,通过构造函数反射创建bean实例。如果是通过构造函数形成的循环依赖,在通过构造函数创建对象时,所依赖的对象必须已经创建,由于循环依赖的对象必须以对方已经存在为前提才能创建,但是在IoC容器启动时,IoC容器中是没有任何bean的,当在doCreateBean方法中调用createBeanInstance方法通过构造函数反射创建对象时,才会创建对象。由于构造函数中依赖的对象不存在,所以要先去创建依赖的对象,此时就不会提前暴露一个工厂,将singletonFactory放到singletonFactories二级缓存中。因此,通过构造函数形成的循环依赖会陷入一个死循环,一直等待依赖的对象先创建。所以spring不支持通过构造函数形成的循环依赖。Spring也不支持原型(prototype)的循环依赖。Spring默认支持单例且非构造方法注入形成的循环依赖

为什么需要三个缓存?二级缓存singletonFactories有什么作用?

因为一级缓存singletonObjects只能存放具有完整生命周期的bean,必须有个缓存用于存放不具有完整生命周期的bean(或者半成品的bean),所以需要三级缓存earlySingletonObjects。

如果不要二级缓存singletonFactories,直接存到三级缓存earlySingletonObjects中,只能存一个对象。假设以前存这个对象的时候,这对象的状态为xa,但是我们这里y要注入的x为xc状态,那么则无法满足。但是如果存一个工厂,工厂根据情况产生任意xa或者xb或者xc等等情况。比如说aop的情况下,x注入y,y也注入x,而y中注入的x需要加代理(aop),但是加代理的逻辑在注入属性之后,也就是x的生命周期走到注入属性的时候,x还不是一个代理对象,那么这个时候把x存起来,然后注入y,获取、创建y,发现y需要注入x,就去三级缓存中获取x,拿出来的x是一个没有代理的对象。但是如果存的是个工厂就不一样,首先把一个能产生x的工厂存起来,然后注入y,注入y的时候获取、创建y,y需要注入x,就去获取x,先从三级缓存中获取,为null,然后从二级缓存拿到一个工厂,调用工厂的getObject方法,spring在getObject方法中判断这个时候x被aop配置了故而需要返回一个代理的x出来注入给y。getObject会根据情况返回一个x,但是这个x是什么状态,spring会自己根据情况返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值