赞
踩
先创建ABean
1.0. 记录正在创建ABean singletonCurrentlyInCreation<ABean>
1.1.实例化ABean–>得到一个对象–>存入singletonFactories
1.2. 填充BBean属性–>去单例池找BBean–>没有就创建
1.3. 进行其他依赖注入
1.4. 初始化前,初始化
1.5. 初始化后
1.6. 放入单例池
创建BBean
2.1. 实例化BBean–>得到一个对象
2.2. 填充ABean属性–>去单例池找ABean–>没有就判断creatingSet–>出现循环依赖–>earlySingletonObjects–>singletonFactories–>Lambda表达式–>执行–> 执行结果创建ABean代理对象或者ABean原始对象,存入earlySingletonObject
2.3. 进行其他依赖注入
2.4. 初始化前,初始化
2.5. 初始化后
2.6. 放入单例池
创建CBean
3.1. 实例化BBean–>得到一个对象
3.2. 填充ABean属性–>去单例池找ABean–>没有就判断creatingSet–>出现循环依赖–>从earlySingletonObjec获取ABean
3.3. 进行其他依赖注入
3.4. 初始化前,初始化
3.5. 初始化后
3.6. 放入单例池
在ABean执行到1.2时会去创建BBean,进入到BBean的生命周期,造成循环依赖
spring为了解决循环依赖进行了三级缓存
1.singletonObjects 单例池
2.earlySingletonObjects 没有经过完整生命周期的单例对象,主要作用时保存单例bean对象,而跳出循环依赖
3.singletonFactories 实例化后没有经过依赖注入的对象,主要作用时生成单例bena对象,并将其存入earlySingletonObjects
//this.getEarlyBeanReference(beanName, mbd, bean)判断是否需要AOP,需要返回AOP代理对象,否则返回原始对象
//该逻辑在bean对象实例化后,依赖注入前
this.addSingletonFactory(beanName, () -> {return this.getEarlyBeanReference(beanName, mbd, bean);});
辅助
@Nullable //从单例池获取bean protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); //判断bean是否在创建中 if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) { //从二级缓存earlySingletonObjects中获取bean对象 singletonObject = this.earlySingletonObjects.get(beanName); //没有获取到bean对象并且允许循环依赖 if (singletonObject == null && allowEarlyReference) { synchronized(this.singletonObjects) { singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { //从二级缓存earlySingletonObjects中获取bean对象 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { //从三级缓存singletonFactories中获取singletonFactory对象 ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName); if (singletonFactory != null) { //执行获取bean对象的逻辑 singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } } } return singletonObject; }
//以下逻辑在bean实例化之后 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"); } //进行三级缓存 this.addSingletonFactory(beanName, () -> { return this.getEarlyBeanReference(beanName, mbd, bean); }); } Object exposedObject = bean; try { //依赖注入 this.populateBean(beanName, mbd, instanceWrapper); //bean初始化,返回bean对象,如果bean因为AOP以外的代理对象生成,且返回的是该对象 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); } if (earlySingletonExposure) { //从单例池拿bean对象,如果因为循环依赖则会从二级缓存中拿到AOP生成的代理对象 Object earlySingletonReference = this.getSingleton(beanName, false); if (earlySingletonReference != null) { //如果是循环依赖生成的earlySingletonReference,判断exposedObject是否非AOP代理对象 if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) { String[] dependentBeans = this.getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length); String[] var12 = dependentBeans; int var13 = dependentBeans.length; for(int var14 = 0; var14 < var13; ++var14) { String dependentBean = var12[var14]; if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } //如果是不同的代理对象,则提示ERROR(避免最后生成的对象不是AOP代理对象,但是循环依赖的BBean依赖注入的是ABean因为AOP生成的代理对象,可以通过在ABean的BBean属性上添加@Laze,则ABean中添加@Async(某些PostProcessor会新生成代理对象,@Transactional不是实现PostProcessor生成代理对象,则不会出现问题)的方法也不会抛出ERROR) if (!actualDependentBeans.isEmpty()) { 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."); } } } }
@Lazy注解会在bean进行依赖注入(以上步骤的第二步)时生成一个代理对象,不会影响bean之后的流程,则不会出现循环依赖。
原型bean无法解决循环依赖问题。
无法实例化对应bean则直接提示ERROR,可在构造器加@Lazy解决。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。