完整脑图下载,加方法注释
3.2 Spring 中Bean的创建流程问题描述:
Spring中存在两个类(类A和类B),A对象中有B对象,B对象中有A对象;
public class A{ private B b; } public class B{ private A a; }Spring容器在初始化时,如何解决这两个Bean的循环依赖问题?
Spring 中 Bean 的创建是分为 实例化和初始化两个步骤的(也只有这样分为两个步骤,才能解决循环依赖的问题)
实例化:仅仅只是完成对象堆空间的开辟,不完成对象属性的赋值 初始化:对对象的属性完成赋值操作
接下来,我们用图解来表示出循环依赖A,B对象的创建过程
3.3 核心步骤&核心代码在我们对上面图片中的对象创建过程进行代码讲解时,我们需要先熟练掌握下面的几段代码块
step1: Spring容器进行对象A的实例化
step2: 实例化的过程中,先会去判断容器中是否有bean对象了(getSingleton():依次从一级缓存到二级缓存到三级缓冲中获取是否存在bean对象);
step3: 此时容器中没有Bean对象的缓存,所以需要去new一个新的A对象;
this.getSingleton(beanName, () -> {return this.createBean(beanName, mbd, args);}
step2: 实例化完A对象后instanceWrapper.getWrappedInstance();,将数据(半成品A)放入三级缓存中
半成品:仅仅完成了实例化,未完成初始化
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
protected void addSingletonFactory(String beanName, ObjectFactory> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized(this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
//放入三级缓存 key:beanName为A,value:lambda表达式
this.singletonFactories.put(beanName, singletonFactory);
//移除二级缓存 beanName为A
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
step3: 三级缓存中放入对象后,进行充A中的B属性this.populateBean(beanName, mbd, instanceWrapper);的操作
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
......
if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
....
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
.....
}
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
....
return this.resolveReference(argName, ref);
....
}
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
....
bean = this.beanFactory.getBean(resolvedName);
...
}
step4: 尝试去获取B对象的缓存,此时容器中没有Bean对象的缓存,所以需要去new一个新的B对象;
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
protected T doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
....
Object sharedInstance = this.getSingleton(beanName);
...
}
step5: 实例化完B对象后instanceWrapper.getWrappedInstance();,将数据(半成品B)放入三级缓存中;
step6: 三级缓存中放入对象后,填充B中的A属性this.populateBean(beanName, mbd, instanceWrapper);
step7: 同样,尝试从缓存中获取A对象来填充B中A的属性,因为之前A对象已经放入三级缓存中了,所以可以直接从缓存中取出A对象的半成品赋值给B对象;
step8: 当成功从三级缓存中获取到A对象时,会将A对象方法二级缓存中,并且从三级缓存中移除A
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
....
//从三级缓存中获取对象
ObjectFactory> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
//当三级缓存中的对象Map不为空时
//ObjectFactory为函数式接口
if (singletonFactory != null) {
//调用Lambda表达式中的方法
singletonObject = singletonFactory.getObject();
//将Key,value放入二级缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
return singletonObject;
}
step9: B对象中的A对象的赋值完成,此时B对象已经是一个完成品(已实例化,已初始化,初始化中的A对象为半成品);(此时B对象已完成,所以我们要继续step3的操作,进行A对象中B对象的赋值操作)。但是在继续step3操作之前,会先调用addSingleton();
protected void addSingleton(String beanName, Object singletonObject) {
synchronized(this.singletonObjects) {
//放入一级缓存beanName: B value:完成品的B对象
this.singletonObjects.put(beanName, singletonObject);
//移除二级、三级缓存
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
step10: B对象已完成创建且赋值,A中B属性的赋值,只需要将返回的对象,赋值给B属性。即完成了循环依赖;
step11: A对象完成赋值操作后,创建操作完成,调用addSingleton();,将完成品的A对象放入一级缓存中,移除二三级缓存的A对象;
step12:此时Spring容器中的缓存里,已经存储有A,B对象的完成品,且完成了循环依赖,上面介绍了A对象创建过程中Spring容器的流程(A对象创建的过程中顺便完成了B对象的创建,并且放到了缓存中)。我们的目的是创建A,B对象,接下来,B对象的创建,Spring尝试从缓存中获取B对象。此时我们发现,B对象的缓存已经存在于Spring容器中,直接返回B对象即可;
核心代码
@FunctionalInterface public interface ObjectFactory参考文档:{ T getObject() throws BeansException; } public class DefaultSingletonBeanRegistry{ //缓存对象:一级缓存 private final Map singletonObjects = new ConcurrentHashMap(256); //缓存对象:三级缓存 private final Map > singletonFactories = new HashMap(16); //缓存对象:二级缓存 private final Map earlySingletonObjects = new ConcurrentHashMap(16); public Object getSingleton(String beanName) { return this.getSingleton(beanName, true); } protected Object getSingleton(String beanName, boolean allowEarlyReference) { //尝试从一级缓存中获取对象 Object singletonObject = this.singletonObjects.get(beanName); //判断一级缓存中对象是否为空 且 为正创建中的对象 if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) { //尝试从二级缓存中获取对象 singletonObject = this.earlySingletonObjects.get(beanName); //判断二级缓存中对象是否为空 if (singletonObject == null && allowEarlyReference) { synchronized(this.singletonObjects) { //尝试从一级缓存中获取对象 singletonObject = this.singletonObjects.get(beanName); //判断一级缓存中对象是否为空 if (singletonObject == null) { //尝试从二级缓存中获取对象 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { //从三级缓存中获取对象 ObjectFactory> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName); //当三级缓存中的对象Map 不为空时 //ObjectFactory为函数式接口 if (singletonFactory != null) { //调用Lambda表达式中的方法 singletonObject = singletonFactory.getObject(); //将Key,value放入二级缓存中 this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } } } return singletonObject; } public Object getSingleton(String beanName, ObjectFactory> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized(this.singletonObjects) { //尝试从一级缓存中获取对象 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { 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 + "'"); } this.beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = this.suppressedExceptions == null; if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet(); } try { //调用lambda表达式 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); } } return singletonObject; } } } public class AbstractAutowireCapableBeanFactory{ protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (this.logger.isTraceEnabled()) { this.logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; Class> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException var9) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9); } Object beanInstance; try { beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse); if (beanInstance != null) { return beanInstance; } } catch (Throwable var10) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10); } try { //调用createBean方法 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); } } 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) { instanceWrapper = this.createBeanInstance(beanName, mbd, args); } //实例化Bean对象 Object bean = instanceWrapper.getWrappedInstance(); Class> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } synchronized(mbd.postProcessingLock) { if (!mbd.postProcessed) { try { this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable var17) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17); } mbd.postProcessed = true; } } 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"); } //调用addSingletonFactory方法,传入形参 bean和ObjectFactory的实现类 this.addSingletonFactory(beanName, () -> { return this.getEarlyBeanReference(beanName, mbd, bean); }); } Object exposedObject = bean; try { //填充属性(填充A对象中的B对象属性或者B对象中填充A对象的属性) this.populateBean(beanName, mbd, instanceWrapper); 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) { Object earlySingletonReference = this.getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) { String[] dependentBeans = this.getDependentBeans(beanName); Set 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); } } 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."); } } } } try { this.registerDisposableBeanIfNecessary(beanName, bean, mbd); return exposedObject; } catch (BeanDefinitionValidationException var16) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16); } } protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { ...... if (pvs != null) { this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs); } } protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { ..... Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); ..... } } public class DefaultSingletonBeanRegistry{ protected void addSingletonFactory(String beanName, ObjectFactory> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); synchronized(this.singletonObjects) { //判断一级缓存中是否含有key为beanName的数据 if (!this.singletonObjects.containsKey(beanName)) { //key:lambda表达式放入三级缓存 this.singletonFactories.put(beanName, singletonFactory); //二级缓存中移除key this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } } }
B站:Spring源码深度解析31精讲,阿里P8架构师讲解的太牛了!



