需要了解循环依赖以及Spring检测到构造器的循环依赖的问题,可以看这篇博文:https://www.cnblogs.com/bhlsheji/p/5208076.html
首先同样是AbstractBeanFactory类的:
doGetBean(String name, @Nullable Class
(注:要了解Spring如何实例化一个对象可以看写的上一篇博文。)
这里直接进入这个方法的单例创建:
源码:
if(mbd.isSingleton()) {
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);
}
进入this.getSingleton方法:
源码:
if(this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if(recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
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;
}
this.afterSingletonCreation(beanName);
}
if(newSingleton) {
this.addSingleton(beanName, singletonObject);
}
由这两段源码可以知道,当出现循环依赖,就会循环调用,当然,如果是其它方式的循环依赖,由于能够直接完成对象初始化只是没有赋值,同时三级缓存提前曝光,所以就能解决这个循环,但构造器注入时产生循环,由于不能初始化对象,所以不能解决这个循环,但spring会检查到这个循环并抛出异常:
例如这两个类:
@Service/*("ous")*/
public class House {
private HouseService houseService;
@Autowired
public House(HouseService houseService){
this.houseService = houseService;
}
}
@Service
public class HouseService {
// @Autowired
// @Qualifier("ous")
private House house;
@Autowired
public HouseService(House house){
this.house = house;
}
}
当创建初始化HouseService调用this.createBean(beanName, mbd, args),由于需要对象House,所以去初始化House,然后House和HouseService一样去初始化通过doGetBean(String name, @Nullable Class
由与这里通过singletonFactory.getObject();的调用,导致this.createBean(beanName, mbd, args)的循环调用,所以一直不会走到
finally {
if(recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
this.afterSingletonCreation(beanName);
}
循环检测的关键方法是this.beforeSingletonCreation(beanName)方法与this.afterSingletonCreation(beanName);
也就让正在创建的Bean总是不能完成初始化,也就不能运行this.afterSingletonCreation方法进行remove。
源码:
protected void beforeSingletonCreation(String beanName) {
if(!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
protected void afterSingletonCreation(String beanName) {
if(!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
this.singletonsCurrentlyInCreation是:
private final Set
由于是Set不能添加相同的Key所以会添加是失败,然后抛出BeanCurrentlyInCreationException异常。
至于Spring如何通过构造器初始化对象,也先不展开说明了,这里为了以后研究一些详情,先记录一下调用堆栈信息,以防忘记:
关键类:AutowiredAnnotationBeanPostProcessor
1、AbstractBeanFactory类的getBean方法
if(mbd.isSingleton()) {
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);
}
2、AbstractAutowireCapableBeanFactory类的:createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
3、doCreateBean方法的:
if(instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
4、createBeanInstance方法的:
return this.autowireConstructor(beanName, mbd, ctors, args);
5、产生一个对象ConstructorResolver
protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor[] ctors, @Nullable Object[] explicitArgs) {
return (new ConstructorResolver(this)).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
6、对象ConstructorResolver的autowireConstructor方法
argsHolder = this.createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, this.getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
7、
convertedValue = this.resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, (TypeConverter)converter, fallback);
8、
return this.beanFactory.resolveDependency(new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
9、
result = this.doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
10、
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
11、
return beanFactory.getBean(beanName);
之后则是循环去获取另一个Bean,当是构造器初始化时则产生循环并抛出异常。