// 循环依赖-添加到三级缓存,在创建Bean的doCreateBean方法中protectedObjectdoCreateBean(String beanName,RootBeanDefinition mbd,@NullableObject[] args)throwsBeanCreationException{......// 如果不支持循环依赖,可以通过设置applicationContext.setAllowCircularReferences(false)进行配置不支持循环依赖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");}// 循环依赖-添加到三级缓存addSingletonFactory(beanName,()->getEarlyBeanReference(beanName, mbd, bean));}......}/**
* 添加三级缓存的具体实现
*/protectedvoidaddSingletonFactory(String beanName,ObjectFactory<?> singletonFactory){Assert.notNull(singletonFactory,"Singleton factory must not be null");// 防止并发synchronized(this.singletonObjects){// 一级缓存不存在的时候进入的判断里面if(!this.singletonObjects.containsKey(beanName)){// 三级缓存把lambda表达式放入进去this.singletonFactories.put(beanName, singletonFactory);// 删除二级缓存this.earlySingletonObjects.remove(beanName);// 记录当前这个Bean正在被创建this.registeredSingletons.add(beanName);}}}
解决循环依赖最核心的代码:一二级缓存找不到会去执行三级缓存的lambda表达式,并放入二级缓存!
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
// 单例池存在Bean
Object singletonObject = this.singletonObjects.get(beanName);
// 单例池不存在,并且正在创建,去二级缓存中找
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
// 二级缓存中不存在并且第二个参数为true(默认为true,放入二级缓存)
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 从三级缓存中得到当前Bean对应的信息
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
// 存在这些信息的时候
if (singletonFactory != null) {
// 执行三级缓存的lambda表达式,并且赋值给外部的结果
singletonObject = singletonFactory.getObject();
// 将执行结果放入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 删除当前数据在三级缓存总的存储值
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
// 返回从单例池,或者早期单例池,或者刚执行完lambda表达式的结果
return singletonObject;
}
进行过循环依赖,实际初始化后(AOP)拿到的值是平台对象,需要从二级缓存中获取代理对象
protectedObjectdoCreateBean(String beanName,RootBeanDefinition mbd,@NullableObject[] args)throwsBeanCreationException{......// 出现了循环依赖if(earlySingletonExposure){// 从二级缓存中拿到提前进行AOP的代理对象Object earlySingletonReference =getSingleton(beanName,false);// 从二级缓存中拿到了代理对象if(earlySingletonReference !=null){// 实际的Bean与初始化后执行完拿到的代理对象一致,赋值从二级缓存拿到的代理对象。// 这里简单理解就是提前进行了AOP,初始化后直接返回了当前的对象if(exposedObject == bean){
exposedObject = earlySingletonReference;}// 不一致的情况,被其他自定义的AOP切面改动了,比如异步@Async也会生成一个代理对象。这时候就会有俩个代理对象!elseif(!this.allowRawInjectionDespiteWrapping &&hasDependentBean(beanName)){// beanName被哪些bean依赖了,现在发现beanName所对应的bean对象发生了改变,那么则会报错String[] dependentBeans =getDependentBeans(beanName);Set<String> actualDependentBeans =newLinkedHashSet<>(dependentBeans.length);for(String dependentBean : dependentBeans){if(!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)){
actualDependentBeans.add(dependentBean);}}if(!actualDependentBeans.isEmpty()){thrownewBeanCurrentlyInCreationException(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.");}}}}......}