02-Spring的循环依赖
三级缓存存放的是什么:
- 一级缓存:成品对象
- 二级缓存:半成品对象
- 三级缓存:lamda表达式,放入的函数是:
getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean)参数bean是方法doCreateBean方法通过反射实例化的对象。
演练一下循环依赖的执行流程:
| 时间点 | A 的状态 | B 的状态 | 关键动作 |
|---|---|---|---|
| 1. 实例化 A | A_raw 生成 | 未创建 | 调用 A 的构造方法。此时不生成代理。 |
| 2. A 放入三级缓存 | A_raw 存在 | 未创建 | 存入 Lambda:() -> getEarlyBeanReference(A)。此时仍不生成代理。 |
| 3. 填充 A 的属性 | A_raw 存在 | 未创建 | 发现依赖 B,暂停 A 的创建,转去创建 B。 |
| 4. 实例化 B | A_raw 存在 | B_raw 生成 | 调用 B 的构造方法。 |
| 5. B 放入三级缓存 | A_raw 存在 | B_raw 存在 | 存入 Lambda:() -> getEarlyBeanReference(B)。 |
| 6. 填充 B 的属性 | A_raw 存在 | B_raw 存在 | 发现依赖 A,调用 getBean(A)。 |
| 7. B 获取 A 的代理 | A_proxy 生成 | B_raw 存在 | 从三级缓存执行 Lambda,A 的代理在此刻生成,放入二级缓存。B_raw 拿到 A_proxy。 |
| 8. B 的属性填充完成 | A_proxy 存在 | B_raw 持有 A_proxy | B 的其他属性注入完成。 |
| 9. B 初始化 | A_proxy 存在 | B_raw 初始化 | 执行 B 的 @PostConstruct、afterPropertiesSet 等。 |
| 10. B 生成最终代理 | A_proxy 存在 | B_proxy 生成 | 经过 BeanPostProcessor,B 的代理在此刻生成,放入一级缓存。 |
| 11. 回到 A 的填充 | A_raw 获取 B_proxy | B_proxy 已存在 | A 的依赖 B 注入完成(拿到 B_proxy)。 |
| 12. A 初始化 | A_raw 初始化 | B_proxy 已存在 | 执行 A 的 @PostConstruct 等。 |
| 13. A 的代理替换 | A_proxy 替代 A_raw | B_proxy 已存在 | Spring 检查二级缓存有 A_proxy,用其替换 A_raw,放入一级缓存。 |
| 14. 最终容器 | A_proxy | B_proxy | 两个代理对象都存在于一级缓存。 |
| 11到13步的处理中“替换”这个概念你可能会有这样的疑问 11.A_raw 获取 B_proxy,二级缓存中的 A_proxy又没获取B_proxy,直接用二级缓存中的 A_proxy代替A_raw,二级缓存中的 A_proxy的属性B不是null的吗? | |||
| 错误的理解(你以为的): |
text
A_proxy {
private B b = null; // 代理对象自己也有这个字段
// ... 其他逻辑
}正确的理解(实际结构):
A_proxy {
private A target; // 指向 A_raw 的引用
// private B b; // 代理对象本身根本没有这个字段!
// 所有业务方法的调用,都会转发给 target
}关键差异:代理对象不复制原始对象的字段,它只持有原始对象的引用。这里一点体现在哪里,是在getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) 参数Object bean相当于A_raw 的引用,方法的返回时A_proxy,通过getEarlyBeanReference方法参数传递给A_proxy。
一,循环依赖产生的原因
所谓的循环依赖是指,A 依赖 B,B 又依赖 A,它们之间形成了循环依赖。
@Component
public class A {
@Autowired
private B b;
}@Component
public class B {
@Autowired
private A a;
}二,Spring源码解析
下图链接地址https://www.processon.com/view/link/6386be8a7d9c086a817680ee

步骤1,调用getBean获取Bean
public Object getBean(String name) throws BeansException {
this.assertBeanFactoryActive();
return this.getBeanFactory().getBean(name);
}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);
Object sharedInstance = this.getSingleton(beanName); // 获取从缓存池中获取bean
Object beanInstance;
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else { // 没有获取到,创建bean
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
return parentBeanFactory.getBean(nameToLookup);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
String[] var12;
if (dependsOn != null) {
var12 = dependsOn;
int var13 = dependsOn.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dep = var12[var14];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var31) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var31);
}
}
}
if (mbd.isSingleton()) { // 如果是单例,创建bean
sharedInstance = this.getSingleton(beanName, () -> {
try {
// 创建createBean
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) { // 多例创建bean
var12 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
beanInstance = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
}
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
this.beforePrototypeCreation(beanName);
Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
return var4;
});
beanInstance = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var30) {
throw new ScopeNotActiveException(beanName, scopeName, var30);
}
}
} catch (BeansException var32) {
beanCreation.tag("exception", var32.getClass().toString());
beanCreation.tag("message", String.valueOf(var32.getMessage()));
this.cleanupAfterBeanCreationFailure(beanName);
throw var32;
} finally {
beanCreation.end();
}
}
return this.adaptBeanInstance(name, beanInstance, requiredType);
}步骤一会调用三次,第一次是获取A,第二次是获取A,发现依赖B获取B调用,第三次是获取B时发现依赖A获取A调用.
步骤2,调用getSingleton从缓存池中获取Bean
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// singletonObjects 从一级缓存中获取对象
Object singletonObject = this.singletonObjects.get(beanName);
// 一级缓存未获取的对象 并且 isSingletonCurrentlyInCreation方法判断当前获取的对象是否在创建中,如果是说明产生了循环依赖,产生循环依赖才会,进入下面的代码.只有调用createBean才会将beanName放入正在创建的集合中。
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
// earlySingletonObjects 从二级缓存中获取对象
singletonObject = this.earlySingletonObjects.get(beanName);
// 一级缓存未获取的对象 并且 allowEarlyReference参数表示是否允许循环依赖
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);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject(); // 创建对象
this.earlySingletonObjects.put(beanName, singletonObject); // 放入二级缓存中
this.singletonFactories.remove(beanName); // 移出三级缓存中的值
}
}
}
}
}
}
return singletonObject;
}步骤二调用情况一:获取A
- 一级缓存(singletonObjects):空的
- 二级缓存为(singletonFactories):空的
- 三级缓存(singletonFactories):空的
- isSingletonCurrentlyInCreation:不包含A,因为还没有真正创建A,调用createBean方法
步骤二调用情况二:创建A发现依赖B,获取B
一级缓存(singletonObjects):空的
二级缓存为(singletonFactories):空的
三级缓存(singletonFactories):A
isSingletonCurrentlyInCreation:包含A,不包含B,因为还没有真正创建B,调用createBean方法
步骤二调用情况三:创建B发现依赖A,再次获取A
一级缓存(singletonObjects):空的
二级缓存为(singletonFactories):A
三级缓存(singletonFactories):
A(移除),BisSingletonCurrentlyInCreation:包含A,包含B
步骤3,调用createBean创建Bean
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
// 创建createBean
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
}this.getSingleton的源码:
// beanName参数是bean的名字
// singletonFactory参数是函数式接口,只有一个getObject()。是三级缓存中存储的
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized(this.singletonObjects) { // 加锁
// 获取一级缓存中的bean
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 + "'");
}
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
singletonObject = singletonFactory.getObject(); // 通过工厂的方式创建bean
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;
}
}singletonFactory是函数接口:
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}所以函数式接口singletonFactory.getObject(); 通过工厂的方式创建bean,是this.createBean(beanName, mbd, args)的返回值.createBean方法的源码如下:
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 {
// 这个地方是BeanPostpress的执行的地方,也是扩展点之一,在实例化之前执行的
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 {
beanInstance = this.doCreateBean(beanName, mbdToUse, args); // 真正创建bean的方法
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);
}
}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) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance(); // 实例化Bean
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;
}
}
// mbd.isSingleton()判断是否是单例的
// this.allowCircularReferences是否允许循环依赖
// this.isSingletonCurrentlyInCreation(beanName) beanname是否是正在创建的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); // 属性赋值
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) { // 再次从二级缓存中获取:目的是解决二级缓存中的是代理后的对象而exposedObject引用的是实例对象
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<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);
}
}
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);
}
}步骤4,实例化对象
Object bean = instanceWrapper.getWrappedInstance(); // 实例化Bean步骤5,放入三级缓存:
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized(this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
// 放入三级缓存
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}放入的 函数是:getEarlyBeanReference()
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
//判读我们容器中是否有InstantiationAwareBeanPostProcessors类型的后置处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//获取我们所有的后置处理器
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判断我们的后置处理器是不是实现了SmartInstantiationAwareBeanPostProcessor接口
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
//进行强制转换
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
//挨个调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}通过Bean的后置处理器创建Bean,这也是判断是否需要生成代理对象的地方。
步骤6,属性赋值
this.populateBean(beanName, mbd, instanceWrapper);用于向 A 这个原始对象中填充属性,当它检测到 A依赖于B时,会首先去实例化 B,调用B的getBean方法获取Bean。
步骤7,初始化
exposedObject = this.initializeBean(beanName, exposedObject, mbd);步骤8,再次调用getSingleton从缓存池中获取Bean
if (earlySingletonExposure) { // 再次从二级缓存中获取:目的是解决二级缓存中的是代理后的对象而exposedObject引用的是实例对象
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<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);
}
}
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.");
}
}
}
}再次获取目的是解决二级缓存中的是代理后的对象而exposedObject引用的是实例对象。这句话的理解,你看你想的你的流程假设 vs Spring的实际流程:
❌ 你的假设流程:
- 创建 A_raw
- 发现依赖 B → 去创建 B
- 创建 B_raw,发现依赖 A
- 从三级缓存获取 Lambda,执行生成 A_proxy
- 将 A_proxy 赋值给 B_raw 的属性
- B_raw 实例化完成 → 生成 B_proxy → 放入一级缓存
- 回到创建 A_raw,从一级缓存获取 B_proxy
- ❓ 问题:A_raw 不是代理对象,但代理在二级缓存,怎么办?
✅ Spring 的实际流程:
- 创建 A_raw
- 将 Lambda 放入三级缓存(此时尚未生成任何代理)
- 发现依赖 B → 去创建 B
- 创建 B_raw,发现依赖 A
- 从三级缓存获取 Lambda,执行 → 生成 A_proxy
- 关键步骤:将 A_proxy 放入二级缓存,同时覆盖掉 A_raw 的引用
- 将 A_proxy 赋值给 B_raw 的属性
- B_raw 完成属性填充 → 初始化 → 生成 B_proxy → 放入一级缓存
- 回到创建 A_raw 的现场,但此时 Spring 已经不再使用 A_raw 了
- A 继续完成属性填充(从一级缓存拿到 B_proxy)
- A 继续初始化,但初始化完成后,Spring 发现二级缓存中已有 A_proxy
- 最终返回给容器的,是二级缓存中的 A_proxy,而不是 A_raw
Spring 的实际流程的伪代码:
// AbstractAutowireCapableBeanFactory.doCreateBean() 简略源码
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 实例化 A,得到 A_raw
Object bean = instanceWrapper.getWrappedInstance(); // A_raw
// 2. 将 Lambda 放入三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 3. 填充属性(这里触发 B 的创建,B 创建过程中从三级缓存取 Lambda,生成 A_proxy,放入二级缓存)
populateBean(beanName, mbd, instanceWrapper);
// 4. 初始化 A(此时 A_raw 的属性已被填充,包括 B_proxy)
Object exposedObject = initializeBean(beanName, bean, mbd); // 这里的 bean 仍是 A_raw
// 5. 【关键】检查是否有提前暴露的代理
if (earlySingletonExposure) {
// 从二级缓存获取提前暴露的 A_proxy
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
// 创建Bean的过程中没有出现2个不同的对象。
if (exposedObject == bean) {
// 将 A_raw 替换为 A_proxy,用二级缓存中的对象(A_proxy)替换exposedObject
exposedObject = earlySingletonReference;
}else if (exposedObject != earlySingletonReference) {
// 如果初始化后的对象 和 提前暴露的对象 不是同一个
// 说明出现了两个不同的对象,抛出异常!
throw new BeanCurrentlyInCreationException(...);
}
}
}
// 6. 返回 exposedObject(此时是 A_proxy)
return exposedObject;
}步骤9,放入一级缓存
在步骤3中创建对象调用得了addSingleton方法,将创建好的对象放入一级缓存中。
protected void addSingleton(String beanName, Object singletonObject) {
synchronized(this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}三,其它问题
1,为什么一级缓存不能解决循环依赖?
首先一级缓存能解决依赖循环依赖,但是无法保证获取的Bean已经完成了属性赋值。
结论:理论上可以,但是实际上没人这样做,使用2个缓存的目的是为了区分成品对象和半成品对象的。
一级缓存失败案例:假设线程Q1调用getBean方法获取A,执行到步骤5将创建对象放入一级缓存后,被阻塞了,此时线程Q2也要获取A,在步骤二中从缓存中拿到了直接返回,但是这个返回的对象并没有完成属性赋值,是一个不完整的对象。
2,为什么二级缓存不能解决要使用三级级缓存解决循环依赖?
可以解决:但是有个前提,没有使用AOP的时候可以。那为什么使用AOP需要三级缓存呢。
首先二级缓存如何解决不安全问题:
在步骤2中从缓存中读取和存储都加锁了:
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);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject(); // 创建对象
this.earlySingletonObjects.put(beanName, singletonObject); // 放入二级缓存中
this.singletonFactories.remove(beanName); // 移出三级缓存中的值
}
}
}
}
}
}
return singletonObject;
}在步骤3中在缓存中存值加锁了:
// beanName参数是bean的名字
// singletonFactory参数是函数式接口,只有一个getObject()。是三级缓存中存储的
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized(this.singletonObjects) { // 加锁
// 获取一级缓存中的bean
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 + "'");
}
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
singletonObject = singletonFactory.getObject(); // 通过工厂的方式创建bean
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;
}
}3,为什么多例Bean不能解决循环依赖?
我们自己手写了解决循环依赖的代码,可以看到,核心是利用一个map,来解决这个问题的,这个map就相当于缓存。为什么可以这么做,因为我们的bean是单例的,而且是字段注入(setter注入)的,单例意味着只需要创建一次对象,后面就可以从缓存中取出来,字段注入,意味着我们无需调用构造方法进行注入。如果是原型bean,那么就意味着每次都要去创建对象,无法利用缓存;如果是构造方法注入,那么就意味着需要调用构造方法注入,也无法利用缓存。
4,为什么Spring不能解决构造器的循环依赖?
从流程图应该不难看出来,在Bean调用构造器实例化之前,一二三级缓存并没有Bean的任何相关信息,在实例化之后才放入三级缓存中,因此当getBean的时候缓存并没有命中,这样就抛出了循环依赖的异常了。
5,循环依赖可以关闭吗?
可以,Spring提供了这个功能,我们需要这么写:
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.setAllowCircularReferences(false); // 设置false
applicationContext.register(AppConfig.class);
applicationContext.refresh();
}
}6,如何进行拓展?
bean可以通过实现SmartInstantiationAwareBeanPostProcessor接口(一般这个接口供spring内部使用)的getEarlyBeanReference方法进行拓展。
7,何时进行拓展?
进行bean的实例化时
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[]args)throws BeanCreationException {
//省略其他代码,只保留了关键代码
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure)
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +11 "' to allow for resolving potential circular references");
}
//添加到三级缓存中
addSingletonFactory(beanName, new ObjectFactory
@Override
public Object getObject()throws BeansException {
//执行拓展的后置处理器
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
}getEarlyBeanReference方法:
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
//判读我们容器中是否有InstantiationAwareBeanPostProcessors类型的后置处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//获取我们所有的后置处理器
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判断我们的后置处理器是不是实现了SmartInstantiationAwareBeanPostProcessor接口
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
//进行强制转换
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
//挨个调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}