Spring的第三级缓存详解 笔记251009
Spring 第三级缓存详解
Spring 的第三级缓存是解决循环依赖和 AOP 代理协同工作的核心机制。下面深入分析第三级缓存的实现原理和工作机制。
第三级缓存的定义与作用
定义
// 在 DefaultSingletonBeanRegistry 中定义
/** 第三级缓存:单例对象工厂的缓存 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
核心作用
- 延迟创建代理对象:只在发生循环依赖时才创建代理
- 保证代理一致性:确保注入的都是正确的代理对象
- 避免资源浪费:没有循环依赖时不提前创建代理
第三级缓存的核心:ObjectFactory
ObjectFactory 接口
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}
在 Spring 中的具体实现
// 添加 ObjectFactory 到三级缓存
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
// 关键:将工厂放入三级缓存
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
第三级缓存的创建时机
Bean 创建过程中的关键节点
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 实例化 Bean
Object bean = createBeanInstance(beanName, mbd, args);
// 2. 判断是否允许提前暴露引用
boolean earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 3. 关键:将 ObjectFactory 添加到三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 4. 属性填充(可能触发循环依赖)
populateBean(beanName, mbd, instanceWrapper);
// 5. 初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
return exposedObject;
}
getEarlyBeanReference 方法深度解析
方法实现
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
// 检查是否有需要处理的后置处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 重点:SmartInstantiationAwareBeanPostProcessor
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp =
(SmartInstantiationAwareBeanPostProcessor) bp;
// 调用后置处理器获取早期引用
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
AOP 代理在第三级缓存中的具体实现
AbstractAutoProxyCreator 的关键方法
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
// 缓存早期代理引用,避免重复创建
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 生成缓存键
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 记录这个 Bean 已经创建了早期代理
this.earlyProxyReferences.put(cacheKey, bean);
// 包装 Bean(如果需要代理则创建代理)
return wrapIfNecessary(bean, beanName, cacheKey);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 关键:如果已经创建过早期代理,这里就不再重复创建
if (!this.earlyProxyReferences.containsKey(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
}
wrapIfNecessary 方法
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果已经处理过,直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 如果不需要代理,直接返回
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 如果是基础设施类或应该跳过的类,直接返回
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取适用的通知
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果找到适用的通知,创建代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
第三级缓存的工作流程实例
场景:A 依赖 B,B 依赖 A,且 A 需要 AOP 代理
// 1. 开始创建 A
Object rawA = instantiateBean("A");
// 2. 将 A 的 ObjectFactory 放入三级缓存
addSingletonFactory("A", () -> {
// 这个 lambda 就是第三级缓存的核心
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof AbstractAutoProxyCreator) {
AbstractAutoProxyCreator aapc = (AbstractAutoProxyCreator) bp;
// 触发 AOP 代理创建
return aapc.getEarlyBeanReference(rawA, "A");
}
}
return rawA;
});
// 3. 填充 A 的属性,发现需要 B
// 4. 开始创建 B
Object rawB = instantiateBean("B");
// 5. 将 B 的 ObjectFactory 放入三级缓存
addSingletonFactory("B", () -> getEarlyBeanReference("B", mbd, rawB));
// 6. 填充 B 的属性,发现需要 A
// 7. 从缓存获取 A
Object earlyA = getSingleton("A", true);
// getSingleton 方法内部:
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) {
// 关键:从三级缓存获取 ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用 getObject() 方法,触发代理创建
singletonObject = singletonFactory.getObject();
// 将对象从三级缓存移到二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
第三级缓存的特殊场景处理
1. 多级代理场景
@Component
public class ServiceA {
@Autowired private ServiceB b;
@Transactional
@Async
public void method() {} // 需要同时支持事务和异步
}
在这种情况下,第三级缓存确保创建正确的复合代理。
2. 自定义 BeanPostProcessor
@Component
public class CustomBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 自定义的早期引用处理逻辑
if (bean instanceof SomeSpecialType) {
return enhanceBean(bean);
}
return bean;
}
}
性能优化考虑
1. 缓存键的设计
// AbstractAutoProxyCreator 中的缓存键生成
protected Object getCacheKey(Class<?> beanClass, String beanName) {
if (StringUtils.hasLength(beanName)) {
return beanName; // 优先使用 beanName
}
return beanClass; // 备用方案使用 Class
}
2. 避免重复处理
// 通过 advisedBeans 缓存避免重复判断
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);
// 通过 earlyProxyReferences 避免重复创建代理
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
总结
Spring 的第三级缓存 (singletonFactories) 是一个精妙的设计,它的核心价值在于:
- 延迟决策:通过
ObjectFactory延迟决定是返回原始对象还是代理对象 - 按需代理:只在发生循环依赖时才提前创建代理对象
- 一致性保证:确保循环依赖中注入的都是正确的代理对象
- 性能优化:避免没有循环依赖时的额外代理创建开销
- 扩展性:通过
SmartInstantiationAwareBeanPostProcessor接口支持自定义扩展
这种设计完美解决了 AOP 代理与循环依赖之间的冲突,是 Spring 框架能够优雅处理复杂依赖关系的基石。
1️⃣ 参考 1
Spring 第三级缓存详解
1. 第三级缓存的本质
第三级缓存是 Spring 解决循环依赖和 AOP 代理协同工作的核心机制,它存储的不是 Bean 实例本身,而是能够创建 Bean 早期引用的工厂对象。
// DefaultSingletonBeanRegistry 中的定义
public class DefaultSingletonBeanRegistry {
// 第三级缓存:存储 ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 其他相关缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); // 一级缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); // 二级缓存
}
2. ObjectFactory 接口详解
2.1 ObjectFactory 定义
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}
这是一个函数式接口,只有一个 getObject() 方法,用于在需要时创建对象。
2.2 第三级缓存中的 ObjectFactory 实现
// 在 doCreateBean 方法中创建并放入三级缓存的 ObjectFactory
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 实例化Bean(构造方法调用)
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
Object bean = instanceWrapper.getWrappedInstance();
// 2. 创建并放入三级缓存的关键代码
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 后续的属性注入、初始化等步骤...
return exposedObject;
}
3. getEarlyBeanReference 方法深度解析
3.1 方法签名和作用
/**
* 获取Bean的早期引用
* @param beanName Bean名称
* @param mbd Bean定义
* @param bean 原始Bean实例(未初始化的)
* @return 可能是原始Bean,也可能是代理对象
*/
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
// 如果有InstantiationAwareBeanPostProcessor,则应用它们
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp =
(SmartInstantiationAwareBeanPostProcessor) bp;
// 关键:这里允许BeanPostProcessor返回代理对象
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
3.2 SmartInstantiationAwareBeanPostProcessor 的作用
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
/**
* 获取指定Bean的早期引用
* 主要用于解决循环依赖,特别是涉及AOP代理的情况
*/
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
4. AbstractAutoProxyCreator 的实现细节
4.1 核心实现类
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
// 缓存早期代理引用,避免重复创建
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 生成缓存key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 记录这个Bean已经创建了早期引用
this.earlyProxyReferences.put(cacheKey, bean);
// 包装Bean(如果需要代理)
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
4.2 早期代理创建的完整流程
// 详细的方法调用链
1. doCreateBean(beanName, mbd, args)
↓
2. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
↓
3. getEarlyBeanReference(beanName, mbd, bean)
↓
4. AbstractAutoProxyCreator.getEarlyBeanReference(bean, beanName)
↓
5. wrapIfNecessary(bean, beanName, cacheKey)
↓
6. createProxy(bean.getClass(), beanName, specificInterceptors, targetSource)
5. 第三级缓存的工作时机和条件
5.1 放入第三级缓存的条件
protected boolean earlySingletonExposure = false;
// 判断是否应该提前暴露单例工厂
earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
// 三个条件必须同时满足:
// 1. mbd.isSingleton() - 必须是单例Bean
// 2. this.allowCircularReferences - 允许循环引用(默认true)
// 3. isSingletonCurrentlyInCreation(beanName) - 当前Bean正在创建中
5.2 从第三级缓存获取的时机
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 先从一级缓存获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 再从二级缓存获取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 最后从三级缓存获取ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用getObject()创建早期引用
singletonObject = singletonFactory.getObject();
// 移动到二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
6. 第三级缓存的特殊场景处理
6.1 多级代理的情况
@Service
public class MultiProxyService {
@Transactional
@Async
@Retryable
public void complexMethod() {
// 多个AOP切面
}
}
// 第三级缓存处理的ObjectFactory会创建包含所有切面的完整代理
ObjectFactory<?> factory = () -> {
Object rawBean = ...; // 原始Bean
// 应用所有BeanPostProcessor,创建包含所有切面的代理
return applyBeanPostProcessorsForEarlyReference(rawBean, beanName);
};
6.2 自定义 BeanPostProcessor 参与
@Component
public class CustomEarlyReferenceProcessor implements SmartInstantiationAwareBeanPostProcessor {
private final Map<String, Object> customEarlyReferences = new HashMap<>();
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
if (bean instanceof CustomBusinessBean) {
// 自定义的早期引用处理逻辑
Object enhancedBean = enhanceForEarlyReference(bean);
customEarlyReferences.put(beanName, bean); // 记录原始Bean
return enhancedBean;
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 检查是否已经处理过早期引用
if (customEarlyReferences.containsKey(beanName)) {
Object original = customEarlyReferences.get(beanName);
if (original == bean) {
// 已经处理过,直接返回
customEarlyReferences.remove(beanName);
return bean;
}
}
// 正常处理
return doCustomProcessing(bean);
}
}
7. 第三级缓存的性能考虑
7.1 内存占用分析
// 第三级缓存的内存结构分析
第三级缓存:Map<String, ObjectFactory<?>> singletonFactories
↓
每个ObjectFactory通常是一个lambda表达式,捕获了:
- beanName (String)
- mbd (RootBeanDefinition)
- bean (Object - 原始Bean引用)
- 当前BeanFactory的引用
// 内存占用相对较小,因为:
// 1. 只在Bean创建期间存在
// 2. 创建完成后立即移除
// 3. ObjectFactory是轻量级的
7.2 并发安全设计
public class DefaultSingletonBeanRegistry {
// 使用synchronized保证线程安全
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 一级缓存查询不需要同步(ConcurrentHashMap)
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 操作二三级缓存时需要同步
synchronized (this.singletonObjects) {
// ... 操作二三级缓存的代码
}
}
return singletonObject;
}
}
8. 调试和监控第三级缓存
8.1 调试工具类
@Component
public class ThirdLevelCacheMonitor implements BeanFactoryAware {
private ConfigurableListableBeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
public void printCacheStatus(String beanName) {
if (beanFactory instanceof DefaultListableBeanFactory) {
DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
DefaultSingletonBeanRegistry registry = (DefaultSingletonBeanRegistry)
dlbf.getSingletonMutex();
// 通过反射访问私有字段(生产环境慎用)
printFieldValue(registry, "singletonObjects", "一级缓存");
printFieldValue(registry, "earlySingletonObjects", "二级缓存");
printFieldValue(registry, "singletonFactories", "三级缓存");
}
}
private void printFieldValue(DefaultSingletonBeanRegistry registry,
String fieldName, String cacheName) {
try {
Field field = DefaultSingletonBeanRegistry.class.getDeclaredField(fieldName);
field.setAccessible(true);
Map<?, ?> cache = (Map<?, ?>) field.get(registry);
System.out.println(cacheName + "大小: " + cache.size());
System.out.println(cacheName + "内容: " + cache.keySet());
} catch (Exception e) {
e.printStackTrace();
}
}
}
8.2 监控第三级缓存的生命周期
@Component
public class CacheLifecycleListener {
@EventListener
public void onContextRefreshed(ContextRefreshedEvent event) {
System.out.println("应用启动完成,三级缓存应该为空");
// 验证三级缓存已清空
}
// 可以监听各种Bean生命周期事件来跟踪缓存状态
}
9. 第三级缓存的设计思想总结
9.1 解决的问题
- 循环依赖:打破 Bean 创建的循环等待
- AOP 代理一致性:确保循环依赖中注入的是代理对象
- 延迟决策:在真正需要时才决定返回原始对象还是代理对象
9.2 设计优势
// 1. 关注点分离
三级缓存各自职责明确:
- 一级缓存:存储完全初始化的Bean
- 二级缓存:存储早期的Bean引用(避免重复创建代理)
- 三级缓存:存储创建早期引用的工厂(支持AOP等扩展)
// 2. 扩展性支持
通过ObjectFactory模式,支持:
- AOP代理
- 自定义BeanPostProcessor
- 其他需要干预Bean创建过程的扩展
// 3. 性能优化
- 按需创建:只在发生循环依赖时才创建早期引用
- 及时清理:Bean创建完成后立即清理对应的缓存
- 避免重复:通过二级缓存避免重复创建代理对象
9.3 实际应用启示
// 理解第三级缓存有助于:
1. 调试复杂的循环依赖问题
2. 理解Spring AOP的工作原理
3. 设计自定义的Bean创建逻辑
4. 优化Bean的初始化性能
// 在实际编码中:
- 尽量避免构造器注入的循环依赖
- 理解@Lazy注解的工作原理
- 在复杂AOP场景中合理设计Bean依赖关系
第三级缓存是 Spring 框架中一个精巧而强大的设计,它通过"工厂模式 + 三级缓存"的架构,优雅地解决了循环依赖和 AOP 代理的协同工作问题,体现了 Spring 框架在复杂场景下的设计智慧。
2️⃣ 参考 2
Spring 第三级缓存详解
1. 第三级缓存的定义与作用
1.1 缓存定义
public class DefaultSingletonBeanRegistry {
// 第三级缓存:存储 ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
}
1.2 核心作用
- 解决循环依赖:在 Bean 尚未完成初始化时提供早期引用
- 支持 AOP 代理:确保在循环依赖中返回正确的代理对象
- 延迟创建:只有在真正需要时才创建 Bean 的早期引用
2. ObjectFactory 接口详解
2.1 接口定义
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}
2.2 在三级缓存中的具体实现
// Bean 实例化后立即创建 ObjectFactory
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
// 核心:将 ObjectFactory 放入三级缓存
this.singletonFactories.put(beanName, singletonFactory);
// 清除二级缓存中的对应项(确保数据一致性)
this.earlySingletonObjects.remove(beanName);
}
}
}
// 具体的 ObjectFactory 创建
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
3. getEarlyBeanReference 方法深度解析
3.1 方法源码
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
// 检查是否需要应用 BeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp =
(SmartInstantiationAwareBeanPostProcessor) bp;
// 关键:允许 BeanPostProcessor 返回包装后的对象(如代理)
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
3.2 SmartInstantiationAwareBeanPostProcessor 的角色
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
// 预测 Bean 类型
Class<?> predictBeanType(Class<?> beanClass, String beanName);
// 选择合适的构造函数
Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName);
// 核心方法:获取早期 Bean 引用
default Object getEarlyBeanReference(Object bean, String beanName) {
return bean;
}
}
4. AbstractAutoProxyCreator 的实现细节
4.1 早期代理引用的创建
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
// 缓存已经创建过早期引用的 Bean
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 生成缓存键
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 记录这个 Bean 已经创建了早期引用
this.earlyProxyReferences.put(cacheKey, bean);
// 包装 Bean(可能创建代理)
return wrapIfNecessary(bean, beanName, cacheKey);
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果已经被处理过,直接返回
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 基础设施类或应该跳过的类
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取适用的通知器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
4.2 避免重复创建代理
@Override
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;
}
5. 第三级缓存的工作流程
5.1 完整的 Bean 创建与缓存流转
public class DefaultSingletonBeanRegistry {
public Object getSingleton(String beanName, boolean allowEarlyReference) {
// 第一步:尝试从一级缓存获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 第二步:尝试从二级缓存获取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 第三步:从三级缓存获取 ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用 ObjectFactory.getObject() 创建早期引用
singletonObject = singletonFactory.getObject();
// 升级到二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 从三级缓存移除
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
}
5.2 三级缓存的完整生命周期
// Bean 创建时间线:
1. 开始创建 Bean → 加入 singletonsCurrentlyInCreation
2. 实例化 Bean → 创建 ObjectFactory 加入三级缓存
3. 属性注入 → 可能触发依赖 Bean 的创建
4. 依赖 Bean 需要当前 Bean → 从三级缓存获取早期引用
5. 早期引用升级到二级缓存
6. Bean 完成初始化 → 加入一级缓存
7. 清理二级缓存和三级缓存
6. 为什么必须使用三级缓存?
6.1 两级缓存的局限性
// 假设只有二级缓存,没有三级缓存:
// 在 Bean 实例化后直接放入二级缓存
earlySingletonObjects.put(beanName, bean);
// 问题1:无法处理 AOP 代理
// 如果 Bean 需要代理,此时放入的是原始对象,不是代理对象
// 问题2:代理创建时机不确定
// 可能在属性注入后才创建代理,导致依赖注入不一致
// 问题3:代码侵入性强
// 需要在实例化时判断是否需要创建代理,违反单一职责原则
6.2 三级缓存的设计优势
// 三级缓存的解决方案:
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 优势1:延迟创建
// 只有在真正发生循环依赖时才创建早期引用
// 优势2:支持扩展
// 通过 BeanPostProcessor 机制支持各种包装(AOP、事务等)
// 优势3:职责分离
// Bean 创建逻辑与循环依赖解决逻辑分离
7. 自定义 ObjectFactory 的扩展点
7.1 自定义 SmartInstantiationAwareBeanPostProcessor
@Component
public class CustomEarlyReferenceProcessor implements SmartInstantiationAwareBeanPostProcessor {
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 自定义早期引用逻辑
if (bean instanceof MySpecialInterface) {
return createCustomWrapper(bean);
}
// 监控或记录早期引用创建
log.debug("Creating early reference for bean: {}", beanName);
return bean;
}
private Object createCustomWrapper(Object bean) {
// 创建自定义包装器
return Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
(proxy, method, args) -> {
// 自定义逻辑
System.out.println("Before method: " + method.getName());
return method.invoke(bean, args);
});
}
}
7.2 性能监控 ObjectFactory
public class MonitoringObjectFactory<T> implements ObjectFactory<T> {
private final ObjectFactory<T> delegate;
private final String beanName;
public MonitoringObjectFactory(ObjectFactory<T> delegate, String beanName) {
this.delegate = delegate;
this.beanName = beanName;
}
@Override
public T getObject() throws BeansException {
long startTime = System.currentTimeMillis();
try {
return delegate.getObject();
} finally {
long duration = System.currentTimeMillis() - startTime;
System.out.println("Early reference creation for " + beanName + " took " + duration + "ms");
}
}
}
8. 调试与问题排查
8.1 查看三级缓存状态
public class CacheInspector {
@Autowired
private ConfigurableApplicationContext context;
public void inspectCaches() {
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)
context.getAutowireCapableBeanFactory();
// 使用反射获取缓存内容
try {
Field singletonFactoriesField = DefaultSingletonBeanRegistry.class
.getDeclaredField("singletonFactories");
singletonFactoriesField.setAccessible(true);
@SuppressWarnings("unchecked")
Map<String, ObjectFactory<?>> singletonFactories =
(Map<String, ObjectFactory<?>>) singletonFactoriesField.get(beanFactory);
System.out.println("三级缓存中的Bean: " + singletonFactories.keySet());
} catch (Exception e) {
e.printStackTrace();
}
}
}
8.2 常见问题分析
问题1:代理对象不一致
// 症状:同一个 Bean 在循环依赖中返回了不同的代理实例
// 原因:可能没有正确使用 earlyProxyReferences 缓存
// 解决方案:检查自定义 BeanPostProcessor 的实现
问题2:三级缓存泄漏
// 症状:Bean 创建失败后,ObjectFactory 仍然在缓存中
// 原因:异常处理逻辑不完善
// 解决方案:确保在 afterSingletonCreation 中清理缓存
9. 性能优化考虑
9.1 ObjectFactory 的创建成本
// 优化:避免不必要的 ObjectFactory 创建
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
// 只有在可能发生循环依赖时才创建
if (isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
}
}
}
}
9.2 懒加载 ObjectFactory
public class LazyObjectFactory<T> implements ObjectFactory<T> {
private final Supplier<T> supplier;
private volatile T instance;
private final Object lock = new Object();
public LazyObjectFactory(Supplier<T> supplier) {
this.supplier = supplier;
}
@Override
public T getObject() throws BeansException {
if (instance == null) {
synchronized (lock) {
if (instance == null) {
instance = supplier.get();
}
}
}
return instance;
}
}
10. 总结
Spring 第三级缓存的设计体现了多个重要的软件设计原则:
10.1 设计原则体现
- 开闭原则:通过 ObjectFactory 接口支持扩展
- 单一职责:三级缓存专注于解决循环依赖中的早期引用问题
- 延迟加载:只有在真正需要时才创建早期引用
10.2 核心价值
- 解决循环依赖:为尚未完成初始化的 Bean 提供引用
- 支持 AOP 代理:确保在循环依赖中返回正确的代理对象
- 提供扩展点:通过 BeanPostProcessor 机制支持自定义包装逻辑
10.3 关键理解点
- 第三级缓存存储的是
ObjectFactory,不是 Bean 实例本身 getEarlyBeanReference方法可能返回代理对象- 三级缓存确保了在整个 Bean 生命周期中代理对象的单例性
理解第三级缓存的工作机制,对于深入掌握 Spring 框架的 Bean 生命周期和循环依赖解决原理至关重要。
3️⃣ 参考 3
Spring 第三级缓存详解
第三级缓存的核心作用
Spring 的三级缓存中,第三级缓存 是最关键且设计最精巧的部分,它专门用于处理循环依赖和 AOP 代理的协同工作。
第三级缓存定义
public class DefaultSingletonBeanRegistry {
// 第三级缓存:存放 ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new ConcurrentHashMap<>(16);
}
ObjectFactory 接口
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}
第三级缓存的存储时机
在 Bean 创建过程中添加
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 实例化 Bean(调用构造方法)
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
Object bean = instanceWrapper.getWrappedInstance();
// 2. 判断是否支持早期暴露
boolean earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 3. 关键:将 ObjectFactory 添加到第三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 4. 后续进行属性注入和初始化
// ...
}
addSingletonFactory 方法详解
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
// 检查一级缓存中是否已存在(防止重复添加)
if (!this.singletonObjects.containsKey(beanName)) {
// 添加到第三级缓存
this.singletonFactories.put(beanName, singletonFactory);
// 清除第二级缓存中的对应项(保持数据一致性)
this.earlySingletonObjects.remove(beanName);
}
}
}
getEarlyBeanReference 方法深度解析
这是第三级缓存的核心逻辑所在:
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
// 检查是否有需要处理的后处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp =
(SmartInstantiationAwareBeanPostProcessor) bp;
// 关键:调用后处理器获取早期引用
// 对于 AOP,这里会返回代理对象
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
AbstractAutoProxyCreator 的实现
AOP 代理的早期引用创建
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
// 记录已经创建早期代理的 Bean
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 生成缓存键
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 记录这个 Bean 已经创建了早期代理
this.earlyProxyReferences.put(cacheKey, bean);
// 创建代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果已经被处理过,直接返回
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 如果是基础设施类或者应该跳过的类,直接返回
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取适用的增强器(Advisors)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果找到适用的增强器,创建代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
第三级缓存的工作流程
完整调用链
1. getBean("A")
2. doGetBean("A")
3. getSingleton("A") [第一次:返回null]
4. createBean("A")
5. doCreateBean("A")
6. addSingletonFactory("A", ObjectFactory) // 添加到三级缓存
7. populateBean("A") → 发现需要 B
8. getBean("B")
9. doGetBean("B")
10. getSingleton("B") [第一次:返回null]
11. createBean("B")
12. doCreateBean("B")
13. addSingletonFactory("B", ObjectFactory) // 添加到三级缓存
14. populateBean("B") → 发现需要 A
15. getBean("A")
16. getSingleton("A", true) [第二次:allowEarlyReference=true]
17. 从三级缓存获取 ObjectFactory
18. objectFactory.getObject() → getEarlyBeanReference()
19. 返回 A 的早期引用(可能是代理对象)
20. 放入二级缓存,移除三级缓存
具体代码执行路径
// 当 B 需要 A 时,调用路径:
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 第一次查找:一级缓存
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 第二次查找:二级缓存
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 第三次查找:三级缓存(关键步骤)
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用 ObjectFactory 创建早期引用
singletonObject = singletonFactory.getObject();
// 移动到二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
为什么需要第三级缓存?
问题场景分析
如果没有第三级缓存,只有二级缓存:
// 假设只有二级缓存的情况
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 直接从二级缓存获取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 无法处理 AOP 代理的情况!
// 因为此时 Bean 还没有经过后处理器的处理
}
}
}
第三级缓存的优势
- 延迟创建:ObjectFactory 只有在需要时才创建早期引用
- AOP 支持:可以在创建早期引用时应用 AOP 代理
- 灵活性:可以根据不同情况返回不同的对象
实际案例演示
案例1:普通 Bean 的循环依赖
@Component
public class ServiceA {
@Autowired
private ServiceB serviceB;
}
@Component
public class ServiceB {
@Autowired
private ServiceA serviceA;
}
第三级缓存处理:
- ServiceA 的 ObjectFactory 返回原始对象
- ServiceB 的 ObjectFactory 返回原始对象
案例2:需要 AOP 代理的 Bean
@Component
public class TransactionalService {
@Autowired
private UserService userService;
@Transactional
public void doSomething() {
// 事务方法
}
}
@Component
public class UserService {
@Autowired
private TransactionalService transactionalService;
}
第三级缓存处理:
- TransactionalService 的 ObjectFactory 返回代理对象
- UserService 的 ObjectFactory 返回原始对象
第三级缓存的特殊处理
1. 防止重复创建代理
@Override
public Object postProcessAfterInitialization(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;
}
2. 处理多个后处理器
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
// 遍历所有 SmartInstantiationAwareBeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp =
(SmartInstantiationAwareBeanPostProcessor) bp;
// 每个处理器都可能修改 exposedObject
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
return exposedObject;
}
调试和监控第三级缓存
1. 查看第三级缓存状态
@Component
public class CacheMonitor {
@Autowired
private ConfigurableApplicationContext context;
public void monitorThirdLevelCache() {
DefaultSingletonBeanRegistry registry = (DefaultSingletonBeanRegistry)
context.getAutowireCapableBeanFactory();
// 使用反射查看三级缓存
try {
Field singletonFactoriesField = DefaultSingletonBeanRegistry.class
.getDeclaredField("singletonFactories");
singletonFactoriesField.setAccessible(true);
Map<String, ObjectFactory<?>> thirdLevelCache =
(Map<String, ObjectFactory<?>>) singletonFactoriesField.get(registry);
System.out.println("第三级缓存大小: " + thirdLevelCache.size());
thirdLevelCache.forEach((beanName, factory) -> {
System.out.println("Bean: " + beanName + ", Factory: " + factory);
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. 自定义 ObjectFactory 进行调试
@Component
public class DebugObjectFactory implements ObjectFactory<Object> {
private static final Logger logger = LoggerFactory.getLogger(DebugObjectFactory.class);
private final ObjectFactory<?> delegate;
private final String beanName;
public DebugObjectFactory(ObjectFactory<?> delegate, String beanName) {
this.delegate = delegate;
this.beanName = beanName;
}
@Override
public Object getObject() throws BeansException {
logger.info("第三级缓存被调用,创建Bean的早期引用: {}", beanName);
long start = System.currentTimeMillis();
Object result = delegate.getObject();
long duration = System.currentTimeMillis() - start;
logger.info("Bean早期引用创建完成: {}, 耗时: {}ms, 类型: {}",
beanName, duration, result.getClass().getSimpleName());
return result;
}
}
性能考虑
1. 第三级缓存的开销
// ObjectFactory 的创建是轻量级的
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 只有在循环依赖实际发生时才会调用 getObject()
2. 缓存命中率优化
// Spring 的优化策略:
// 1. 尽早将 ObjectFactory 移动到二级缓存
// 2. 及时清理不再需要的缓存项
// 3. 使用 ConcurrentHashMap 提高并发性能
总结
Spring 的第三级缓存是解决循环依赖和 AOP 代理协同工作的核心机制:
- 存储内容:ObjectFactory,用于延迟创建早期引用
- 关键方法:
getEarlyBeanReference()处理 AOP 代理 - 工作时机:Bean 实例化后、属性注入前
- 设计优势:
- 支持 AOP 代理与循环依赖的协同
- 避免重复创建代理对象
- 提供灵活的早期引用创建机制
理解第三级缓存的工作原理,对于深入掌握 Spring IoC 容器、排查循环依赖问题以及优化应用性能都具有重要意义。
4️⃣ 参考 4
Spring 第三级缓存深度详解
1. 第三级缓存的本质
1.1 定义和位置
第三级缓存在 Spring 源码中的定义:
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
// 第三级缓存:存放 ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 其他相关缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); // 一级缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); // 二级缓存
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
}
1.2 ObjectFactory 接口
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}
关键特性:
- 函数式接口,只有一个
getObject()方法 - 延迟执行:只有在调用
getObject()时才真正创建对象 - 支持 lambda 表达式创建
2. 第三级缓存的核心作用
2.1 主要职责
第三级缓存的三个核心作用:
- 延迟创建早期引用
- 支持 AOP 代理的特殊处理
- 保证 Bean 引用的正确性
2.2 与 AOP 的深度集成
// 第三级缓存中存储的实际上是这个 lambda 表达式
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// getEarlyBeanReference 方法的完整实现
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
// 如果不是合成 Bean 且有 InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 找到 SmartInstantiationAwareBeanPostProcessor
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp =
(SmartInstantiationAwareBeanPostProcessor) bp;
// 关键:这里可能返回代理对象而不是原始对象
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
3. 第三级缓存的工作机制
3.1 存储时机
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 实例化 Bean(调用构造函数)
Object beanInstance = createBeanInstance(beanName, mbd, args);
// 2. 判断是否允许早期暴露
boolean earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 3. 将 ObjectFactory 放入第三级缓存
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
// 这个 lambda 会在需要早期引用时执行
return getEarlyBeanReference(beanName, mbd, beanInstance);
}
});
}
// 4. 继续后续的属性注入和初始化
// ...
}
3.2 获取时机
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 首先尝试从一级缓存获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 然后尝试从二级缓存获取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 最后从三级缓存获取 ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 关键:调用 getObject() 创建早期引用
singletonObject = singletonFactory.getObject();
// 将创建的早期引用放入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 从三级缓存移除,因为已经创建了早期引用
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
4. 为什么必须使用第三级缓存?
4.1 两级缓存的局限性
假设只有两级缓存(一级 + 二级):
// 伪代码:两级缓存方案
public class TwoLevelCacheRegistry {
private Map<String, Object> singletonObjects = new HashMap<>(); // 一级
private Map<String, Object> earlySingletonObjects = new HashMap<>(); // 二级
public void addEarlyBean(String beanName, Object bean) {
// 问题:在实例化后立即放入二级缓存
earlySingletonObjects.put(beanName, bean);
}
public Object getSingleton(String beanName) {
Object bean = singletonObjects.get(beanName);
if (bean == null) {
bean = earlySingletonObjects.get(beanName); // 直接返回早期对象
}
return bean;
}
}
两级缓存的问题:
- 无法处理 AOP 代理:在实例化时无法确定是否需要创建代理
- 资源浪费:即使没有循环依赖,也会创建早期引用
- 时机不当:在 Bean 属性注入前就固定了对象引用
4.2 第三级缓存的优势
// 三级缓存的精妙之处
addSingletonFactory(beanName, () -> {
// 延迟执行:只有在真正需要时才创建早期引用
Object earlyReference = getEarlyBeanReference(beanName, mbd, bean);
// 在这里可以:
// 1. 检查 Bean 是否需要 AOP 代理
// 2. 应用所有相关的 BeanPostProcessor
// 3. 返回适当的对象(原始对象或代理对象)
return earlyReference;
});
第三级缓存的优势:
| 特性 | 两级缓存 | 三级缓存 |
|---|---|---|
| AOP 支持 | 有限 | 完整支持 |
| 资源使用 | 可能浪费 | 按需创建 |
| 创建时机 | 过早固定 | 延迟创建 |
| 灵活性 | 低 | 高 |
5. 源码深度分析
5.1 addSingletonFactory 方法详解
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
// 确保 Bean 还没有被完全创建
if (!this.singletonObjects.containsKey(beanName)) {
// 放入三级缓存
this.singletonFactories.put(beanName, singletonFactory);
// 清除二级缓存中的对应项(确保一致性)
this.earlySingletonObjects.remove(beanName);
// 注册已注册的单例(用于销毁时清理)
this.registeredSingletons.add(beanName);
}
}
}
5.2 AbstractAutoProxyCreator 的关键实现
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
// 用于跟踪已经创建早期代理的 Bean
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 生成缓存键
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 记录这个 Bean 已经创建了早期代理
this.earlyProxyReferences.put(cacheKey, bean);
// 包装 Bean(如果需要代理则创建代理)
return wrapIfNecessary(bean, beanName, cacheKey);
}
@Override
public Object postProcessAfterInitialization(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;
}
}
6. 复杂场景分析
6.1 多层循环依赖 + AOP
@Service
public class ServiceA {
@Autowired private ServiceB serviceB;
@Transactional
public void methodA() {}
}
@Service
public class ServiceB {
@Autowired private ServiceC serviceC;
}
@Service
public class ServiceC {
@Autowired private ServiceA serviceA; // 三层循环依赖
}
执行流程:
-
ServiceA 创建
// 实例化 ServiceA // 将 ObjectFactory 放入三级缓存:singletonFactories.put("serviceA", factoryA) -
ServiceA 注入 ServiceB
// 触发 ServiceB 的创建 -
ServiceB 创建
// 实例化 ServiceB // 将 ObjectFactory 放入三级缓存:singletonFactories.put("serviceB", factoryB) -
ServiceB 注入 ServiceC
// 触发 ServiceC 的创建 -
ServiceC 创建
// 实例化 ServiceC // 将 ObjectFactory 放入三级缓存:singletonFactories.put("serviceC", factoryC) -
ServiceC 注入 ServiceA
// 从三级缓存获取 ServiceA 的早期引用 ObjectFactory<?> factoryA = singletonFactories.get("serviceA"); Object serviceAProxy = factoryA.getObject(); // 触发 AOP 代理创建 // 将代理对象放入二级缓存 earlySingletonObjects.put("serviceA", serviceAProxy); singletonFactories.remove("serviceA");
6.2 多个 Bean 依赖同一个 AOP 代理
@Service
public class ServiceX {
@Autowired private CommonService commonService;
}
@Service
public class ServiceY {
@Autowired private CommonService commonService;
}
@Service
@Transactional
public class CommonService {
// 需要 AOP 代理
}
第三级缓存确保:
- 所有依赖方获取到的是同一个代理实例
- 代理只创建一次,即使被多个 Bean 依赖
7. 特殊 BeanPostProcessor 的影响
7.1 自定义 SmartInstantiationAwareBeanPostProcessor
@Component
public class CustomBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
// 在第三级缓存的 ObjectFactory 中会被调用
if (bean instanceof MySpecialBean) {
// 对特定 Bean 进行特殊处理
return enhanceBean(bean);
}
return bean;
}
private Object enhanceBean(Object bean) {
// 创建增强版本
return Enhancer.create(bean.getClass(),
(MethodInterceptor) (obj, method, args, proxy) -> {
System.out.println("Before method: " + method.getName());
Object result = proxy.invokeSuper(obj, args);
System.out.println("After method: " + method.getName());
return result;
});
}
}
7.2 多个后处理器的执行顺序
// 第三级缓存中的执行顺序
Object earlyReference = bean;
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp =
(SmartInstantiationAwareBeanPostProcessor) bp;
// 按顺序应用所有 SmartInstantiationAwareBeanPostProcessor
earlyReference = ibp.getEarlyBeanReference(earlyReference, beanName);
}
}
8. 调试和问题排查
8.1 查看第三级缓存内容
@Component
public class CacheDebugger implements ApplicationContextAware {
private ConfigurableApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = (ConfigurableApplicationContext) applicationContext;
}
public void debugThirdLevelCache() {
DefaultSingletonBeanRegistry registry = (DefaultSingletonBeanRegistry)
applicationContext.getBeanFactory();
// 使用反射查看三级缓存内容
try {
Field singletonFactoriesField = DefaultSingletonBeanRegistry.class
.getDeclaredField("singletonFactories");
singletonFactoriesField.setAccessible(true);
@SuppressWarnings("unchecked")
Map<String, ObjectFactory<?>> singletonFactories =
(Map<String, ObjectFactory<?>>) singletonFactoriesField.get(registry);
System.out.println("第三级缓存中的 Bean 数量: " + singletonFactories.size());
for (String beanName : singletonFactories.keySet()) {
System.out.println("第三级缓存 Bean: " + beanName);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
8.2 常见问题排查
问题 1:Bean 在三级缓存但获取不到
// 可能原因:allowEarlyReference 参数为 false
Object bean = getSingleton(beanName, false); // 不会访问三级缓存
问题 2:ObjectFactory 执行异常
// 在 getEarlyBeanReference 中添加调试
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
try {
// 原有逻辑
} catch (Exception e) {
System.err.println("创建早期引用失败: " + beanName);
throw e;
}
}
9. 性能考虑和最佳实践
9.1 性能影响
第三级缓存的性能特点:
- 内存开销:存储 ObjectFactory 比存储实际对象更轻量
- 计算开销:延迟创建避免了不必要的代理创建
- 并发安全:使用 synchronized 保证线程安全
9.2 最佳实践
// 1. 避免在 ObjectFactory 中执行耗时操作
addSingletonFactory(beanName, () -> {
// 避免:执行数据库查询、网络请求等
// 推荐:只做必要的 Bean 包装和代理创建
return getEarlyBeanReference(beanName, mbd, bean);
});
// 2. 合理设计 Bean 依赖,减少复杂循环依赖
// 3. 对于不需要 AOP 的 Bean,考虑使用构造器注入避免循环依赖
10. 总结
Spring 的第三级缓存是解决循环依赖和 AOP 代理协同工作的核心机制:
核心价值:
- 延迟创建:只有在真正需要时才创建早期引用
- AOP 集成:完美支持代理对象的循环依赖
- 资源优化:避免不必要的早期对象创建
- 一致性保证:确保所有依赖方使用相同的对象引用
设计哲学:
- 通过 ObjectFactory 实现"懒加载"模式
- 分离 Bean 创建和代理创建的关注点
- 在灵活性和性能之间取得平衡
理解第三级缓存的工作机制,对于深入掌握 Spring 框架的设计思想和解决复杂的 Bean 创建问题具有重要意义。
5️⃣ 参考 5
Spring 第三级缓存详解
1. 第三级缓存的本质与定义
1.1 第三级缓存的源码定义
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
// 第三级缓存:单例工厂对象缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 相关缓存定义
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); // 一级缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); // 二级缓存
}
1.2 ObjectFactory 接口定义
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}
2. 第三级缓存的特殊作用
2.1 与一二级缓存的本质区别
| 缓存级别 | 存储内容 | 特点 |
|---|---|---|
| 一级缓存 | 完全初始化的 Bean 实例 | 直接可用的最终对象 |
| 二级缓存 | 早期暴露的 Bean 实例 | 半成品对象,已实例化但未完成初始化 |
| 三级缓存 | ObjectFactory 工厂对象 | 延迟决策机制,支持动态创建代理 |
2.2 第三级缓存的不可替代性
// 如果没有第三级缓存,只有二级缓存会面临的问题:
// 场景:Bean A 依赖 Bean B,Bean B 依赖 Bean A,且都需要 AOP 代理
// 问题1:何时创建代理?
// - 如果实例化后立即创建代理放入二级缓存:可能创建不必要的代理
// - 如果等到初始化后创建代理:循环依赖时无法注入代理对象
// 问题2:代理一致性
// - 如何确保循环依赖中注入的代理与最终代理是同一个对象?
// 第三级缓存的解决方案:
// - 存储 ObjectFactory,延迟代理创建决策
// - 在真正需要时才决定返回原始对象还是代理对象
3. 第三级缓存的核心机制
3.1 添加到第三级缓存的时机
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 实例化 Bean(创建原始对象)
Object beanInstance = instantiateBean(beanName, mbd);
// 2. 判断是否需要提前暴露(解决循环依赖的关键)
boolean earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 关键:添加到第三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, beanInstance));
}
// 3. 后续的属性填充、初始化等步骤...
}
3.2 addSingletonFactory 方法详解
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
// 添加到第三级缓存
this.singletonFactories.put(beanName, singletonFactory);
// 清理二级缓存(确保数据一致性)
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
4. getEarlyBeanReference 深度解析
4.1 方法执行流程
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
// 检查是否有需要处理的后处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp =
(SmartInstantiationAwareBeanPostProcessor) bp;
// 关键:让后处理器决定返回原始对象还是包装后的对象
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
4.2 AOP 代理的特殊处理
// AnnotationAwareAspectJAutoProxyCreator 的实现
public class AnnotationAwareAspectJAutoProxyCreator extends AbstractAutoProxyCreator {
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 生成缓存键
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 记录原始对象,避免重复创建代理
this.earlyProxyReferences.put(cacheKey, bean);
// 包装为代理(如果需要)
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
5. 第三级缓存的调用时机
5.1 循环依赖触发第三级缓存
// 获取 Bean 的核心逻辑
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 快速从一级缓存检查
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 检查二级缓存
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 关键:从第三级缓存获取 ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用 ObjectFactory 创建早期引用
singletonObject = singletonFactory.getObject();
// 升级到二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
5.2 完整的调用链条
// 第三级缓存的完整调用流程:
1. Bean A 开始创建
2. Bean A 实例化(原始对象)
3. Bean A 的 ObjectFactory 添加到第三级缓存
4. Bean A 属性填充 → 需要 Bean B
5. Bean B 开始创建
6. Bean B 实例化(原始对象)
7. Bean B 的 ObjectFactory 添加到第三级缓存
8. Bean B 属性填充 → 需要 Bean A
9. 获取 Bean A:
- 一级缓存:无
- 二级缓存:无
- 三级缓存:找到 Bean A 的 ObjectFactory
- 调用 singletonFactory.getObject()
→ getEarlyBeanReference()
→ 如果需要 AOP,返回代理对象
→ 否则返回原始对象
10. Bean A 的早期引用放入二级缓存
11. Bean B 完成创建
12. Bean A 完成创建
6. 第三级缓存与 AOP 的深度集成
6.1 代理决策的延迟性
// 第三级缓存支持延迟代理决策的示例:
@Service
public class UserService {
@Autowired
private OrderService orderService;
// 条件化代理:根据配置决定是否需要事务
@Transactional(condition = "
########## {@environment.getProperty('app.feature.tx-enabled', true)}")
public void updateUser() {
// 方法实现
}
}
// 处理流程:
1. UserService 实例化,ObjectFactory 放入三级缓存
2. 此时不知道是否需要创建代理(配置可能还没加载)
3. 当 OrderService 需要注入 UserService 时,调用 ObjectFactory.getObject()
4. 此时检查配置,动态决定是否创建代理
5. 返回原始对象或代理对象
6.2 多阶段代理处理
public class AdvancedAutoProxyCreator extends AbstractAutoProxyCreator {
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 阶段1:早期代理创建(解决循环依赖)
Object earlyProxy = createEarlyProxy(bean, beanName, cacheKey);
// 记录创建信息
this.earlyProxyReferences.put(cacheKey, bean);
return earlyProxy;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 阶段2:检查是否需要完善代理
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 早期没有创建代理,现在创建完整代理
return wrapIfNecessary(bean, beanName, cacheKey);
} else {
// 早期已经创建代理,检查是否需要重新包装
return maybeReWrapProxy(bean, beanName, cacheKey);
}
}
private Object createEarlyProxy(Object bean, String beanName, Object cacheKey) {
// 创建基础代理(可能不包含所有功能)
// 用于解决循环依赖,后续可能被完善
return createBasicProxy(bean, beanName);
}
private Object maybeReWrapProxy(Object bean, String beanName, Object cacheKey) {
// 检查是否需要为早期代理添加额外功能
if (needsEnhancedProxy(bean, beanName)) {
return createEnhancedProxy(bean, beanName);
}
return bean;
}
}
7. 第三级缓存的特殊场景
7.1 多 BeanPostProcessor 协同工作
// 多个 SmartInstantiationAwareBeanPostProcessor 的场景
@Component
public class CustomBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 自定义处理逻辑
if (bean instanceof CustomAnnotatedBean) {
return wrapWithCustomProxy(bean);
}
return bean;
}
}
// 执行顺序:
1. UserService 实例化
2. 第三级缓存中的 ObjectFactory 被调用
3. 遍历所有 SmartInstantiationAwareBeanPostProcessor:
- CustomBeanPostProcessor.getEarlyBeanReference()
- AnnotationAwareAspectJAutoProxyCreator.getEarlyBeanReference()
- 其他后处理器...
4. 每个后处理器都可能包装对象
5. 返回最终处理后的对象
7.2 条件化代理创建
public class ConditionalProxyCreator extends AbstractAutoProxyCreator {
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 根据条件决定是否创建代理
if (shouldCreateEarlyProxy(bean, beanName)) {
return super.getEarlyBeanReference(bean, beanName);
}
// 直接返回原始对象
return bean;
}
private boolean shouldCreateEarlyProxy(Object bean, String beanName) {
// 条件1:是否存在循环依赖
boolean hasCircularDependency = checkCircularDependency(beanName);
// 条件2:Bean 是否需要代理
boolean needsProxy = needsProxy(bean, beanName);
// 条件3:配置是否允许早期代理
boolean configAllowed = isEarlyProxyEnabled();
return hasCircularDependency && needsProxy && configAllowed;
}
}
8. 第三级缓存的性能优化
8.1 延迟创建的优点
// 第三级缓存的性能优势:按需创建
public class OptimizedObjectFactory implements ObjectFactory<Object> {
private final Object rawBean;
private final String beanName;
private final BeanDefinition beanDefinition;
private volatile Object cachedInstance;
@Override
public Object getObject() throws BeansException {
// 双重检查锁定,避免重复创建
if (cachedInstance == null) {
synchronized (this) {
if (cachedInstance == null) {
// 只有真正需要时才执行昂贵的代理创建
cachedInstance = createProxyIfNecessary(rawBean, beanName, beanDefinition);
}
}
}
return cachedInstance;
}
private Object createProxyIfNecessary(Object bean, String beanName, BeanDefinition bd) {
// 昂贵的代理创建逻辑
if (needsProxy(bean, beanName)) {
long start = System.nanoTime();
Object proxy = createProxy(bean, beanName);
long end = System.nanoTime();
log.debug("创建代理耗时: {} ns", end - start);
return proxy;
}
return bean;
}
}
8.2 缓存清理策略
public class SmartSingletonBeanRegistry extends DefaultSingletonBeanRegistry {
// 智能清理第三级缓存
public void cleanUpSingletonFactories() {
synchronized (this.singletonObjects) {
Iterator<Map.Entry<String, ObjectFactory<?>>> iterator =
this.singletonFactories.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ObjectFactory<?>> entry = iterator.next();
String beanName = entry.getKey();
// 清理长时间未使用的 ObjectFactory
if (shouldRemoveFactory(beanName)) {
iterator.remove();
log.debug("清理第三级缓存: {}", beanName);
}
}
}
}
private boolean shouldRemoveFactory(String beanName) {
// 条件1:Bean 已经完成初始化
if (this.singletonObjects.containsKey(beanName)) {
return true;
}
// 条件2:ObjectFactory 创建后长时间未被使用
if (isFactoryStale(beanName)) {
return true;
}
return false;
}
}
9. 调试与监控第三级缓存
9.1 第三级缓存监控工具
@Component
public class ThirdLevelCacheMonitor implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private AbstractApplicationContext context;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext() == context) {
monitorThirdLevelCache();
}
}
private void monitorThirdLevelCache() {
DefaultSingletonBeanRegistry registry = (DefaultSingletonBeanRegistry)
context.getBeanFactory();
try {
Field singletonFactoriesField =
DefaultSingletonBeanRegistry.class.getDeclaredField("singletonFactories");
singletonFactoriesField.setAccessible(true);
@SuppressWarnings("unchecked")
Map<String, ObjectFactory<?>> thirdLevelCache =
(Map<String, ObjectFactory<?>>) singletonFactoriesField.get(registry);
System.out.println("=== 第三级缓存状态 ===");
System.out.println("缓存大小: " + thirdLevelCache.size());
for (Map.Entry<String, ObjectFactory<?>> entry : thirdLevelCache.entrySet()) {
String beanName = entry.getKey();
ObjectFactory<?> factory = entry.getValue();
System.out.println("Bean: " + beanName);
System.out.println(" Factory: " + factory.getClass().getSimpleName());
// 尝试分析工厂行为
analyzeObjectFactory(beanName, factory);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void analyzeObjectFactory(String beanName, ObjectFactory<?> factory) {
try {
// 使用反射分析 ObjectFactory 的行为
Method getObjectMethod = factory.getClass().getMethod("getObject");
// 检查是否会创建代理
if (willCreateProxy(factory)) {
System.out.println(" 可能创建代理");
} else {
System.out.println(" 返回原始对象");
}
} catch (Exception e) {
System.out.println(" 分析失败: " + e.getMessage());
}
}
}
9.2 第三级缓存追踪器
@Component
public class ThirdLevelCacheTracer {
private final Map<String, List<String>> factoryAccessLog = new ConcurrentHashMap<>();
@EventListener
public void onBeanFactoryAccess(BeanFactoryAccessEvent event) {
if (event.getCacheLevel() == 3) {
String beanName = event.getBeanName();
factoryAccessLog.computeIfAbsent(beanName, k -> new ArrayList<>())
.add("Accessed at: " + System.currentTimeMillis());
}
}
public void printAccessStatistics() {
System.out.println("=== 第三级缓存访问统计 ===");
factoryAccessLog.forEach((beanName, accesses) -> {
System.out.println(beanName + ": " + accesses.size() + " 次访问");
if (accesses.size() > 1) {
System.out.println(" 多次访问可能表示性能问题");
}
});
}
}
10. 第三级缓存的最佳实践
10.1 合理设计避免过度依赖
// 良好的设计减少对第三级缓存的依赖
@Service
public class WellDesignedService {
// 方案1:使用接口隔离
private final UserRepository userRepository;
private final OrderRepository orderRepository;
// 构造器注入,明确依赖
public WellDesignedService(UserRepository userRepository, OrderRepository orderRepository) {
this.userRepository = userRepository;
this.orderRepository = orderRepository;
}
// 方案2:使用方法注入避免字段循环依赖
@Autowired
public void setDependencies(UserRepository userRepository,
@Lazy OrderService orderService) {
this.userRepository = userRepository;
// 使用 @Lazy 打破循环
}
// 方案3:使用事件驱动解耦
@EventListener
public void handleUserEvent(UserEvent event) {
// 事件处理,避免直接方法调用
}
}
10.2 性能优化配置
@Configuration
public class CacheOptimizationConfig {
@Bean
public static BeanFactoryPostProcessor cacheOptimizer() {
return beanFactory -> {
if (beanFactory instanceof ConfigurableListableBeanFactory) {
ConfigurableListableBeanFactory configurableFactory =
(ConfigurableListableBeanFactory) beanFactory;
// 优化第三级缓存相关配置
optimizeThirdLevelCache(configurableFactory);
}
};
}
private static void optimizeThirdLevelCache(ConfigurableListableBeanFactory factory) {
// 配置尽早清理未使用的 ObjectFactory
if (factory instanceof DefaultSingletonBeanRegistry) {
DefaultSingletonBeanRegistry registry = (DefaultSingletonBeanRegistry) factory;
// 可以在这里添加自定义的缓存清理策略
scheduleCacheCleanup(registry);
}
}
}
总结
Spring 第三级缓存的核心价值:
核心特性:
- 延迟决策机制:存储 ObjectFactory 而非具体对象
- 动态代理支持:在需要时才决定是否创建代理
- AOP 集成:与 BeanPostProcessor 深度集成
- 性能优化:避免不必要的代理创建
设计优势:
- 解决循环依赖:为循环依赖提供早期引用
- 支持复杂代理场景:处理条件化代理、多层代理等
- 保证一致性:确保整个应用中代理对象的一致性
- 提供扩展点:通过 ObjectFactory 支持自定义逻辑
理解要点:
- 第三级缓存不是存储 Bean,而是存储创建 Bean 的工厂
- ObjectFactory.getObject() 是代理决策的关键时机
- 第三级缓存与 AOP 代理创建机制紧密耦合
- 合理使用可以显著提升应用性能和稳定性
掌握第三级缓存的工作原理对于理解 Spring 容器的完整生命周期、排查复杂的循环依赖问题以及进行深度性能优化都具有重要意义。
6️⃣ 参考 6
Spring第三级缓存详解:与AOP协同解决循环依赖的核心机制
一、第三级缓存的核心定义与结构
Spring的第三级缓存(singletonFactories)本质是一个ConcurrentHashMap<String, ObjectFactory<?>>,存储的是Bean的工厂对象(ObjectFactory)。其核心作用是延迟生成Bean的早期引用(可能包含AOP代理),确保在循环依赖场景下能正确注入代理对象。
- 与其他缓存的协作:
- 一级缓存(singletonObjects):存储完全初始化的Bean,直接供调用者使用。
- 二级缓存(earlySingletonObjects):存储已实例化但未初始化的Bean(原始对象或代理对象),避免重复生成实例。
- 三级缓存(singletonFactories):存储工厂对象,仅在需要时(如循环依赖)通过工厂生成早期引用,并放入二级缓存。
二、第三级缓存解决循环依赖的流程
以BeanA依赖BeanB,BeanB又依赖BeanA为例:
-
创建BeanA:
- 实例化
BeanA(调用构造器),此时BeanA仅为空对象。 - 将
BeanA的ObjectFactory存入三级缓存,标记为“正在创建”。
- 实例化
-
填充BeanA的属性:
- 发现
BeanA依赖BeanB,开始创建BeanB。
- 发现
-
创建BeanB:
- 实例化
BeanB,将其ObjectFactory存入三级缓存。 - 填充
BeanB的属性时,发现依赖BeanA。
- 实例化
-
解决BeanB对BeanA的依赖:
- 从一级缓存未找到
BeanA,转而从二级缓存查找。 - 二级缓存未找到,从三级缓存获取
BeanA的ObjectFactory。 - 调用
ObjectFactory.getObject()生成BeanA的早期引用(可能是代理对象):- 若
BeanA需要AOP增强(如@Transactional),工厂会生成代理对象。 - 将代理对象存入二级缓存,并从三级缓存移除
BeanA的工厂。
- 若
BeanB注入BeanA的代理对象,完成初始化后存入一级缓存。
- 从一级缓存未找到
-
完成BeanA的初始化:
BeanA从一级缓存获取已初始化的BeanB,完成属性注入。BeanA初始化完成后存入一级缓存,并从二级缓存移除其早期引用。
三、第三级缓存与AOP的协同机制
-
代理对象的延迟生成:
- 三级缓存的工厂对象(
ObjectFactory)在生成早期引用时,会通过SmartInstantiationAwareBeanPostProcessor判断是否需要创建代理。 - 例如,
BeanA被@Transactional注解标记,工厂会生成其代理对象(如AProxy),而非原始对象。 - 确保循环依赖中注入的是代理对象,而非可能过期的原始对象。
- 三级缓存的工厂对象(
-
避免重复代理:
- 若直接通过二级缓存存储原始对象,当
BeanA需要代理时,BeanB会持有原始对象,而最终BeanA会被代理为AProxy,导致BeanB依赖与最终实例不一致。 - 三级缓存通过工厂动态生成代理,保证所有依赖方获取的是同一实例(原始对象或代理对象)。
- 若直接通过二级缓存存储原始对象,当
-
性能优化:
- 仅在发生循环依赖时调用工厂生成代理,避免提前创建不必要的代理对象。
- 若无循环依赖,工厂不会被触发,Bean会正常初始化并生成代理(如需要),减少性能开销。
四、第三级缓存的必要性分析
-
为何不能仅用二级缓存?
- 二级缓存存储的是已生成的对象(原始或代理),无法动态决定是否需要代理。
- 若
BeanA需要代理,但二级缓存中存储的是原始对象,BeanB注入的会是过期引用,导致最终实例不一致。
-
三级缓存的“延迟”特性:
- 延迟生成:工厂对象仅在需要时生成实例,避免提前代理的资源浪费。
- 动态决策:根据Bean是否需要AOP增强,动态返回原始对象或代理对象。
五、源码关键点解析
-
getSingleton方法:protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 从一级缓存获取 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { // 从二级缓存获取 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { // 从三级缓存获取工厂并生成实例 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); // 存入二级缓存,移除三级缓存 this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; } -
addSingletonFactory方法:protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { // 存入三级缓存,移除二级缓存中的旧数据 this.singletonFactories.put(beanName, singletonFactory); this.earlySingletonObjects.remove(beanName); } } } -
getEarlyBeanReference方法:protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } } return exposedObject; }- 遍历所有
SmartInstantiationAwareBeanPostProcessor(如AbstractAutoProxyCreator),提前完成代理操作。
- 遍历所有
六、总结:第三级缓存的核心价值
-
解决循环依赖与AOP的冲突:
- 通过工厂对象动态生成代理,确保循环依赖中注入的是正确实例。
-
性能优化:
- 延迟代理生成,避免不必要的资源消耗。
-
线程安全:
- 通过同步块保证多线程环境下缓存的一致性。
-
设计精妙性:
- 三级缓存的分层设计(工厂→早期实例→完全实例)完美平衡了灵活性、性能与正确性。
7️⃣ 参考 7
Spring第三级缓存详解
1. 三级缓存的定义与结构 Spring通过三级缓存机制解决单例Bean的循环依赖问题,核心是三个Map容器:
- 一级缓存(singletonObjects):存储完全初始化完成的单例Bean实例,可直接使用。
- 二级缓存(earlySingletonObjects):存储提前暴露的“半成品”Bean(已实例化但未属性注入/初始化),用于解决循环依赖。
- 三级缓存(singletonFactories):存储
ObjectFactory(工厂方法),动态生成Bean实例(如AOP代理),是解决循环依赖的关键。
2. 三级缓存的工作原理 核心流程(以A依赖B、B依赖A的循环依赖为例):
- 创建Bean A:
- 实例化A(空对象),将其工厂方法存入三级缓存。
- 属性注入时发现依赖B,触发B的创建。
- 创建Bean B:
- 实例化B,工厂方法存入三级缓存。
- 属性注入时发现依赖A,从三级缓存获取A的工厂方法。
- 通过工厂生成A的半成品(若A需AOP则生成代理对象),存入二级缓存并移除三级缓存中的工厂。
- 将半成品A注入B,完成B的初始化后移入一级缓存。
- 完成Bean A:
- A从二级缓存获取B(已完全初始化),完成属性注入和初始化,移入一级缓存。
关键逻辑:
- 缓存查找顺序:一级 → 二级 → 三级。
- 三级缓存通过
ObjectFactory延迟生成代理对象,确保AOP逻辑在循环依赖场景下正确应用。
3. 与AOP的协同关系
- AOP代理的延迟生成:三级缓存的工厂方法在需要时(如其他Bean依赖该Bean)动态生成代理对象,避免直接使用原始实例导致代理逻辑缺失。
- 解决代理对象的循环依赖:若Bean需AOP(如
@Transactional),三级缓存确保代理对象在属性填充前生成,其他Bean注入的是代理而非原始实例。 - 示例场景:ServiceA依赖ServiceB,且B需事务管理。创建B时,其工厂方法存入三级缓存;当A依赖B时,工厂生成B的代理对象存入二级缓存,A注入该代理对象,确保事务逻辑生效。
4. 特殊场景与限制
- 构造器注入的循环依赖:无法解决,因构造器执行时Bean尚未实例化完成,Spring会抛出
BeanCurrentlyInCreationException。 - 多例Bean的循环依赖:不支持,因每次获取都是新实例,无法通过缓存解决。
- 设计建议:循环依赖可能指示设计问题,应通过重构(如解耦、使用
@Lazy延迟加载)避免。
5. 源码与配置要点
- 核心源码:
DefaultSingletonBeanRegistry中的三个Map,以及getSingleton()方法实现缓存查找逻辑。 - 配置示例:
- 允许循环依赖(Spring Boot 2.6+默认禁用):
spring: main: allow-circular-references: true - 字段/setter注入支持循环依赖,构造器注入不支持。
- 允许循环依赖(Spring Boot 2.6+默认禁用):
6. 总结 Spring第三级缓存通过“工厂方法+延迟生成”机制,在解决循环依赖的同时支持AOP代理,确保单例Bean在复杂依赖场景下正确初始化。开发者需理解其工作原理,合理设计Bean以避免循环依赖,或在必要时通过配置和重构优化依赖关系。
8️⃣ 参考 8
Spring 的第三级缓存(singletonFactories)是其 DefaultSingletonBeanRegistry 类中定义的三个核心缓存之一,是解决单例 Bean 循环依赖,特别是与 AOP(面向切面编程)协同工作的最关键、最精妙的设计。
1. 基本定义
- 名称:
singletonFactories - 类型:
ConcurrentHashMap<String, ObjectFactory<?>> - 作用: 存放能够创建早期 Bean 引用(Early Bean Reference)的工厂对象(
ObjectFactory)。 - 位置: 位于
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry类中。
2. 核心职责:延迟创建与智能代理
第三级缓存的核心思想是 “不直接存放对象,而是存放创建对象的工厂”。这带来了两个至关重要的优势:
-
延迟创建 (Lazy Creation):
- 在 Bean 实例化完成后,Spring 并不立即将原始对象暴露给其他 Bean。
- 而是创建一个
ObjectFactory,将其放入三级缓存。这个工厂就像一个“承诺”或“生产指令”,只有当其他 Bean 真正需要这个依赖时,才会触发工厂的getObject()方法来创建对象。 - 这避免了不必要的对象暴露和潜在的资源浪费。
-
智能代理 (Smart Proxying):
- 这是三级缓存存在的根本原因。
ObjectFactory的getObject()方法内部会调用getEarlyBeanReference()。 getEarlyBeanReference()会触发SmartInstantiationAwareBeanPostProcessor类型的后置处理器,特别是AbstractAutoProxyCreator(AOP 的核心实现)。- 在这个阶段,Spring 就能判断当前 Bean 是否需要被 AOP 增强(例如,是否有
@Transactional、@Cacheable等注解)。 - 如果需要,则在此刻创建代理对象并返回;如果不需要,则返回原始对象。
- 这是三级缓存存在的根本原因。
3. 详细工作流程(结合 AOP)
让我们通过一个具体的例子来理解第三级缓存的生命周期:
场景: ServiceA 依赖 ServiceB,ServiceB 依赖 ServiceA,且 ServiceA 有 @Transactional 注解。
-
创建
ServiceA- 实例化- Spring 开始创建
ServiceA。 - 通过构造函数或工厂方法,
ServiceA被实例化(new ServiceA()),此时对象已存在,但属性未注入。 - 关键步骤: Spring 调用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))。 - 这个 Lambda 表达式
() -> getEarlyBeanReference(...)就是ObjectFactory的核心。 - 此时,
ServiceA的ObjectFactory被放入第三级缓存singletonFactories。ServiceA的原始对象尚未暴露。
- Spring 开始创建
-
注入
ServiceA的依赖 - 创建ServiceBServiceA需要注入ServiceB,于是 Spring 开始创建ServiceB。ServiceB经历同样的过程:实例化 → 将其ObjectFactory放入第三级缓存。
-
ServiceB需要注入ServiceA(循环依赖点)- 当为
ServiceB注入ServiceA时,Spring 调用getSingleton("serviceA", true)。 - 检查一级缓存(完整Bean)和二级缓存(早期引用)都没有
ServiceA。 - 检查第三级缓存
singletonFactories,发现存在ServiceA的ObjectFactory。 - 调用
ObjectFactory.getObject()。 getObject()内部执行getEarlyBeanReference("serviceA", mbd, serviceAInstance)。getEarlyBeanReference遍历BeanPostProcessor,发现AbstractAutoProxyCreator。AbstractAutoProxyCreator检查到ServiceA有@Transactional,于是在此刻创建了一个 CGLIB 代理对象ServiceA$$EnhancerByCGLIB。- 将这个代理对象返回。
- 当为
-
从第三级缓存“升级”到第二级缓存
- Spring 将
getEarlyBeanReference返回的对象(即代理对象)放入第二级缓存earlySingletonObjects。 - 同时,从第三级缓存
singletonFactories中移除ServiceA的ObjectFactory。 - 这一步非常重要,保证了早期引用只会被创建一次,避免重复代理。
- 将这个代理对象注入到
ServiceB中。
- Spring 将
-
后续流程
ServiceB完成创建,放入一级缓存。ServiceA继续完成属性注入(注入ServiceB),执行初始化方法。- 在
postProcessAfterInitialization阶段,AbstractAutoProxyCreator再次被调用,但它会识别到代理已经创建,直接返回同一个代理对象。 - 最终,同一个代理对象被放入一级缓存
singletonObjects。
4. 为什么必须是三级?二级缓存为什么不行?
假设没有第三级缓存,只有二级缓存:
ServiceA实例化后,直接将原始对象放入二级缓存。ServiceB从二级缓存拿到的是原始对象。- 后续
ServiceA初始化时,创建了代理对象并放入一级缓存。 - 结果:
ServiceB持有的是ServiceA的原始对象(无事务功能)。- 其他地方获取的是
ServiceA的代理对象(有事务功能)。 - 对象不一致,单例原则被破坏。
ServiceB调用ServiceA的方法时,事务不会生效,AOP 失效。
第三级缓存的 ObjectFactory 解决了这个问题:它确保了无论何时、何地获取 ServiceA 的早期引用,都是通过同一个工厂创建的,并且在创建时就考虑了 AOP 需求,从而保证了最终所有引用都指向同一个最终形态的对象(代理或原始对象)。
5. 总结
Spring 的第三级缓存 singletonFactories 是一个设计极其精巧的机制:
- 它是一个工厂缓存,存放的是
ObjectFactory,而不是直接的对象。 - 它的核心价值在于
getEarlyBeanReference(),这个方法使得 AOP 代理可以在 Bean 初始化的极早期阶段就被创建。 - 它保证了对象一致性,解决了循环依赖与 AOP 代理之间的根本矛盾。
- 它是 Spring 能够同时支持循环依赖和 AOP 的基石。
可以将第三级缓存理解为 Spring IoC 容器中的一个“智能制造车间”:它不直接展示产品,而是提供一个生产指令。当有人需要产品时,这个车间会根据最新的“增强需求”(AOP 配置),现场制造出一个带有“特殊功能”(代理)的成品,确保交付的每一件产品都是完整且一致的。
9️⃣ 参考 9
Spring第三级缓存详解
什么是第三级缓存
Spring的第三级缓存(singletonFactories)是Spring IoC容器解决循环依赖问题的核心机制之一,它存储的是Bean实例的工厂对象(ObjectFactory),这些工厂对象可以用来在Bean创建过程中提前生成Bean的早期引用。
第三级缓存的定义与实现
在Spring源码中,第三级缓存的定义如下:
// DefaultSingletonBeanRegistry类中
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
它是一个Map,键是Bean的名称,值是ObjectFactory类型的对象,用于创建Bean实例。
第三级缓存的核心作用
1. 解决循环依赖问题 当Bean A依赖Bean B,Bean B又依赖Bean A时,Spring需要在Bean A完全初始化之前就将其暴露给Bean B使用。第三级缓存提供了这个"提前暴露"的机制。
2. 支持AOP代理的提前生成 这是第三级缓存最重要的作用。当Bean需要被AOP代理时,Spring可以在Bean创建的早期阶段就生成代理对象,而不是等到Bean完全初始化后。
第三级缓存的工作流程
1. 创建Bean A的流程
- Spring开始创建Bean A
- 实例化Bean A(此时Bean A是"半成品",属性未注入)
- 将Bean A的工厂对象(
ObjectFactory)放入第三级缓存addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, singletonFactory)); - Bean A需要依赖Bean B,于是开始创建Bean B
2. 创建Bean B的流程
- Spring开始创建Bean B
- Bean B需要依赖Bean A,于是查找Bean A
- 从第三级缓存中获取Bean A的工厂对象
- 通过工厂对象生成Bean A的早期引用(可能已应用AOP代理)
- 将生成的Bean A早期引用放入第二级缓存(
earlySingletonObjects) - 从第三级缓存中移除Bean A的工厂对象
- Bean B完成初始化,放入第一级缓存(
singletonObjects)
3. 回到Bean A的创建
- Bean A从第一级缓存获取到完整的Bean B
- Bean A完成属性注入和初始化
- Bean A放入第一级缓存
- 从第二级缓存中移除Bean A的早期引用
第三级缓存与AOP的关系(关键点)
为什么需要第三级缓存来支持AOP
根据知识库[2]的描述:
"不用3级缓存,那么对象的初始化就要提到实例化过程中,会破坏spring的整体流程"
关键原因:
- 如果没有第三级缓存,每次需要获取Bean的早期引用时,都会重新生成代理对象
- 这会导致重复生成代理对象,造成性能问题和不一致状态
- 第三级缓存提供了一个"工厂",可以在需要时生成代理对象,确保只生成一次
AOP代理的生成时机
在Spring中,AOP代理的生成发生在getEarlyBeanReference方法中:
protected Object getEarlyBeanReference(String beanName, Object bean) {
// 如果有AOP配置,在此处生成代理对象
return applyBeanPostProcessorsBeforeInstantiation(bean.getClass(), beanName);
}
这个方法在Bean创建的早期阶段(实例化后、属性注入前)被调用,生成AOP代理对象。
第三级缓存 vs 第二级缓存
| 缓存 | 作用 | 存储内容 | 生成时机 | 用途 |
|---|---|---|---|---|
| 第三级缓存(singletonFactories) | 生成Bean的工厂 | ObjectFactory | Bean实例化后,属性注入前 | 提前暴露Bean的"工厂",用于生成早期引用 |
| 第二级缓存(earlySingletonObjects) | 存储早期Bean引用 | 已生成的Bean(可能已应用AOP) | 从第三级缓存获取工厂后生成 | 为依赖方提供"半成品"Bean的引用 |
为什么需要第三级缓存(不是只有两级缓存)
根据知识库[2]的说明:
"只需要一级和三级缓存也可以做到解决循环依赖的问题,只要两个缓存确实可以做到解决循环依赖的问题,但是有一个前提这个bean没被AOP进行切面代理,如果这个bean被AOP进行了切面代理,那么只使用两个缓存是无法解决问题"
原因:
- 如果没有AOP,确实可以只用两级缓存解决循环依赖
- 但如果有AOP,必须使用第三级缓存
- 第三级缓存确保了AOP代理对象可以被正确地提前暴露,而不会重复生成
第三级缓存的源码实现
在Spring的DefaultSingletonBeanRegistry类中,第三级缓存的关键方法:
// 将Bean的工厂放入第三级缓存
public 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);
}
}
}
// 从第三级缓存获取工厂,生成早期Bean引用
protected Object getEarlyBeanReference(String beanName, ObjectFactory<?> singletonFactory) {
Object bean = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, bean);
this.singletonFactories.remove(beanName);
return bean;
}
第三级缓存的生命周期
- 创建阶段:在Bean实例化后,但属性注入前,将工厂放入第三级缓存
- 使用阶段:当其他Bean需要这个Bean的早期引用时,从第三级缓存获取工厂,生成早期Bean
- 清理阶段:将生成的早期Bean放入第二级缓存,并从第三级缓存中移除工厂
- 完成阶段:当Bean完全初始化后,放入第一级缓存,从第二级缓存中移除
实际应用示例
// A类,被AOP代理
@Component
@Aspect
public class A {
@Autowired
private B b;
// AOP切面方法
@Before("execution(* com.example.service.*.*())")
public void before() {
System.out.println("Before A");
}
}
// B类
@Component
public class B {
@Autowired
private A a;
}
在这个例子中:
- Spring创建A时,将A的工厂放入第三级缓存
- 创建B时,需要A,从第三级缓存获取工厂
- 通过工厂生成A的代理对象(已应用AOP)
- 将代理对象放入第二级缓存
- B完成初始化
- A使用B的代理对象,完成初始化
总结
Spring的第三级缓存(singletonFactories)是解决循环依赖和AOP代理问题的关键机制:
- 核心功能:存储Bean的工厂对象,用于在Bean创建过程中提前生成Bean的早期引用
- 与AOP的关系:确保AOP代理可以在Bean创建的早期阶段生成,避免重复代理
- 设计目的:解决循环依赖问题,同时支持AOP代理的提前暴露
- 必要性:在AOP场景下,第三级缓存是不可或缺的,没有它就无法正确处理AOP代理与循环依赖的双重问题
第三级缓存的设计体现了Spring IoC容器的精妙之处,它不仅解决了循环依赖问题,还优雅地整合了AOP功能,保证了Bean创建过程的一致性和正确性。
🔟 参考 10
Spring 的第三级缓存(singletonFactories)是解决循环依赖与 AOP 代理协同问题的关键设计,它的核心价值在于延迟生成早期对象的引用,确保在复杂依赖场景下 Bean 的正确初始化。
三级缓存的本质
第三级缓存是一个 Map<String, ObjectFactory<?>> 结构,其中:
- Key 是 Bean 的名称
- Value 是
ObjectFactory接口的实现,用于在需要时生成 Bean 的早期引用
ObjectFactory 是一个函数式接口,核心方法 getObject() 用于创建或获取对象:
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}
在 Spring 中,这个工厂的默认实现逻辑是:当调用 getObject() 时,会通过 getEarlyBeanReference() 方法生成对象的早期引用,如果该 Bean 需要 AOP 增强,这里会直接生成代理对象。
为什么需要第三级缓存?
-
解决 AOP 代理与循环依赖的冲突
若没有三级缓存,直接将原始对象放入二级缓存,当 Bean 需要 AOP 增强时,循环依赖注入的会是原始对象,而最终初始化完成的是代理对象,导致不一致。
三级缓存通过工厂延迟生成代理对象,确保注入的是代理对象(如果需要增强)。 -
避免不必要的代理对象生成
只有当发生循环依赖时,才会通过工厂生成早期引用(可能是代理)。若没有循环依赖,代理对象会在 Bean 完全初始化后生成,符合正常流程。 -
支持 SmartInstantiationAwareBeanPostProcessor 扩展
工厂会触发SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference()方法,允许自定义早期引用的生成逻辑(如 AOP 代理)。
三级缓存的工作流程(结合循环依赖) 假设场景:Bean A 依赖 Bean B,Bean B 依赖 Bean A,且 A 需要 AOP 增强。
-
初始化 A:
- 实例化 A(调用构造器,未设置属性)
- 创建 A 的工厂并放入三级缓存:
singletonFactories.put("a", () -> getEarlyBeanReference("a", mbd, a))
-
A 需要注入 B,开始初始化 B:
- 实例化 B
- B 需要注入 A,尝试从缓存获取 A:
- 一级缓存(
singletonObjects)无(A 未初始化完成) - 二级缓存(
earlySingletonObjects)无 - 从三级缓存获取 A 的工厂,调用
getObject():- 触发 AOP 代理生成(因为 A 需要增强)
- 将生成的 A 代理对象放入二级缓存,同时移除三级缓存中的工厂
- 一级缓存(
-
B 注入 A 的代理对象后完成初始化,放入一级缓存
-
A 注入 B 后继续初始化:
- 检查是否存在早期暴露的引用(即二级缓存中的 A 代理)
- 若存在,以代理对象作为 A 的最终实例,放入一级缓存
核心源码位置
三级缓存的操作集中在 DefaultSingletonBeanRegistry 中:
// 三级缓存定义
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 添加工厂到三级缓存
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() 方法在 AbstractAutowireCapableBeanFactory 中实现,是生成早期引用的关键:
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
}
}
return exposedObject;
}
总结
第三级缓存通过 ObjectFactory 实现了延迟生成早期引用的机制,既解决了循环依赖问题,又保证了 AOP 代理的正确注入。它的设计体现了 Spring 对复杂场景的细致处理,是容器初始化过程中的核心环节。