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会自己根据情况返回。