Spring源码:三级缓存

本文详细探讨了Spring的三级缓存机制,包括singletonObjects(一级缓存)、earlySingletonObjects(二级缓存)和singletonFactories(三级缓存)。在解决循环依赖问题时,这些缓存起着关键作用,确保了bean的正确创建和引用。通过实例化、属性填充和初始化过程,展示了三级缓存如何协同工作以避免死循环。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

循环依赖

两个或两个以上对象互相依赖对方,形成一个依赖环,例如A对象依赖B对象,B对象依赖A对象。

当创建相互依赖的对象时,会形成死循环,例如下图无缓存中的情况。而Spring通过增加缓存,将未完全创建好的A提前暴露在缓存中,当相互依赖的对象B对属性A赋值时,可以直接从缓存中获取A,而不需要再创建A,例如下图有缓存中的情况。

Spring的三级缓存

Spring的三级缓存分别为:

  • singletonObject:一级缓存,缓存中的bean是已经创建完成的,该bean经历过实例化->属性填充->初始化以及各种的后置处理。因此,一旦需要获取bean时,会优先寻找一级缓存

 
 

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) { // bean创建前操作,标记当前bean正在创建 beforeSingletonCreation(beanName); boolean newSingleton = false; try { // 创建bean singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (Exception ex) { // ... } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } // bean创建后操作,删除当前bean正在创建 afterSingletonCreation(beanName); } if (newSingleton) { // 存入一级缓存 addSingleton(beanName, singletonObject); } } return singletonObject; } } // 在bean创建完成之后,将bean加入到一级缓存中 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); } } 复制代码

  • earlySingletonObjects:二级缓存,该缓存跟一级缓存的区别在于,该缓存所获取到的bean是提前曝光出来的,是还没创建完成的。也就是说获取到的bean只能确保已经进行了实例化,但是属性填充跟初始化还没有做完,因此该bean还没创建完成,时半成品,仅仅能作为指针提前曝光,被其他bean所引用

 
 

// 二级缓存是从三级缓存中通过getObject()方法获取的 protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { singletonObject = this.earlySingletonObjects.get(beanName); 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) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { // 三级缓存通过getObject()方法获取半成品bean singletonObject = singletonFactory.getObject(); // 存放二级缓存 this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } } } return singletonObject; } 复制代码

  • singletonFactories:三级缓存,在bean实例化完之后,属性填充以及初始化之前,如果允许提前曝光,spring会将实例化后的bean提前曝光,也就是把该bean转换成beanFactory并加入到三级缓存。在需要引用提前曝光对象时再通过singletonFactory.getObject()获取。

 
 

// 在实例化bean之后,如果允许循环依赖,将未创建完的bean加入到三级缓存 if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } // 存入三级缓存 addSingletonFactory(beanName, () -> 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)) { // 存放三级缓存 this.singletonFactories.put(beanName, singletonFactory); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } } 复制代码

三级缓存的使用

当A和B相互依赖时,若先创建实例A,则整个调用过程为:

其中涉及缓存和依赖相关主要过程为:

  • 开始创建实例A,标记A为正在创建

 
 

protected void beforeSingletonCreation(String beanName) { // 将实例A加入到singletonsCurrentlyInCreation中 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } } 复制代码

  • 实例化A后,将未赋值和初始化的实例A加入到三级缓存singletonFactories中

 
 

addSingletonFactory(beanName, () -> 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)) { // 放入三级缓存 this.singletonFactories.put(beanName, singletonFactory); // 二级缓存删除该bean this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } } 复制代码

  • 由于循环依赖,实例A触发实例B加载,标记B为正在创建,并在实例化B后,将未赋值和初始化的实例B加入到三级缓存singletonFactories中(同上)

  • 由于循环依赖,实例B触发实例A加载,在缓存中获取到未创建好的A

 
 

protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 一级缓存中不存在A,返回null Object singletonObject = this.singletonObjects.get(beanName); // A因为已经标记为正在创建,进入下面的if语句 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // 二级缓存不存在A,返回null 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) { // 三级缓存中存在未创建好的实例A,获取到ObjectFactory对象 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { // 调用getObject()方法,获取到为创建好的实例A singletonObject = singletonFactory.getObject(); // 将实例A放入到二级缓存中 this.earlySingletonObjects.put(beanName, singletonObject); // 三级缓存中删除实例A this.singletonFactories.remove(beanName); } } } } } } return singletonObject; } 复制代码

  • 在B创建好之后,则标记实例B创建完成,并将B加入到一级缓存中

 
 

protected void afterSingletonCreation(String beanName) { // 将实例B从singletonsCurrentlyInCreation中删除 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); } } protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { // 将实例B放入一级缓存 this.singletonObjects.put(beanName, singletonObject); // 三级缓存中删除B this.singletonFactories.remove(beanName); // 二级缓存中删除B this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } 复制代码

  • 在A创建好之后,则标记实例A创建完成,并将A加入到一级缓存中

AOP和三级缓存

不涉及AOP

实例加入到三级缓存,并从三级缓存中获取实例过程如下:

 
 

// 添加到三级缓存 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); // 使用三级缓存 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } 复制代码

从三级缓存获取到的bean,是经过getEarlyBeanReference()作用之后返回的bean,在不涉及AOP时,没有类覆盖实现getEarlyBeanReference()方法,使用getEarlyBeanReference()的默认实现,因此返回的bean就是实例化后的原始bean。

 
 

default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { return bean; } 复制代码

涉及AOP

当涉及到AOP时,AbstractAutoProxyCreator实现了getEarlyBeanReference()方法,返回的bean是经过AOP代理的bean。

 
 

public Object getEarlyBeanReference(Object bean, String beanName) { Object cacheKey = getCacheKey(bean.getClass(), beanName); this.earlyProxyReferences.put(cacheKey, bean); // 创建AOP代理 return wrapIfNecessary(bean, beanName, cacheKey); } 复制代码

不涉及循环依赖时,bean的AOP代理是在实例化,赋值,初始化之后创建的。而涉及循环依赖时,三级缓存中保存的是实例化但未赋值,初始化之后的bean,当通过三级缓存获取实例时,则会提前创建AOP代理:

  • 非循环依赖,在实例化,赋值,初始化之后创建AOP代理

  • 循环依赖,在实例化,未赋值,初始化之后创建AOP代理(提前创建代理)

对于在缓存中提前创建好代理的实例,当赋值,初始化之后,运行至bean的后置处理逻辑,即AbstractAutoProxyCreator的 postProcessAfterInitialization方法(正常创建AOP代理逻辑)时,则不会再次创建AOP代理,返回的是不经代理的bean。

 
 

// AbstractAutoProxyCreator的后置处理逻辑 public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { // 由于提前创建了代理并且有缓存,则不再返回代理 Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } 复制代码

再返回赋值和初始化bean的逻辑中,exposedObject作为最终的返回结果,在使用到AOP时,最终返回的都是代理bean

 
 

// 原始bean Object exposedObject = bean; try { // 实例赋值 populateBean(beanName, mbd, instanceWrapper); // 实例初始化(初始化后调用bean的后置处理逻辑,即创建AOP代理) // (1)非循环依赖,未提前创建代理,initializeBean返回的是代理bean // (2)循环依赖,提前创建代理,initializeBean返回的是原始bean exposedObject = initializeBean(beanName, exposedObject, mbd); } if (earlySingletonExposure) { // 当allowEarlyReference=false时,只能从一级二级缓存中获取实例 // (1)未提前创建代理时,实例在三级缓存中,getSingleton返回代理null // (2)提前创建代理时,实例在二级缓存中,返回代理bean Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { // 提前创建代理,代理bean在缓存中,所以下面相等 if (exposedObject == bean) { // 将代理bean赋值给exposedObject exposedObject = earlySingletonReference; } // ... } }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值