Spring的第三级缓存详解 笔记251009

58 阅读58分钟

Spring的第三级缓存详解 笔记251009

Spring 第三级缓存详解

Spring 的第三级缓存是解决循环依赖和 AOP 代理协同工作的核心机制。下面深入分析第三级缓存的实现原理和工作机制。

第三级缓存的定义与作用

定义
// 在 DefaultSingletonBeanRegistry 中定义
/** 第三级缓存:单例对象工厂的缓存 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
核心作用
  1. 延迟创建代理对象:只在发生循环依赖时才创建代理
  2. 保证代理一致性:确保注入的都是正确的代理对象
  3. 避免资源浪费:没有循环依赖时不提前创建代理

第三级缓存的核心: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) 是一个精妙的设计,它的核心价值在于:

  1. 延迟决策:通过 ObjectFactory 延迟决定是返回原始对象还是代理对象
  2. 按需代理:只在发生循环依赖时才提前创建代理对象
  3. 一致性保证:确保循环依赖中注入的都是正确的代理对象
  4. 性能优化:避免没有循环依赖时的额外代理创建开销
  5. 扩展性:通过 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 解决的问题

  1. 循环依赖:打破 Bean 创建的循环等待
  2. AOP 代理一致性:确保循环依赖中注入的是代理对象
  3. 延迟决策:在真正需要时才决定返回原始对象还是代理对象

    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 核心价值

  1. 解决循环依赖:为尚未完成初始化的 Bean 提供引用
  2. 支持 AOP 代理:确保在循环依赖中返回正确的代理对象
  3. 提供扩展点:通过 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 还没有经过后处理器的处理
        }
    }
}

    第三级缓存的优势

  1. 延迟创建:ObjectFactory 只有在需要时才创建早期引用
  2. AOP 支持:可以在创建早期引用时应用 AOP 代理
  3. 灵活性:可以根据不同情况返回不同的对象

实际案例演示

    案例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 代理协同工作的核心机制:

  1. 存储内容:ObjectFactory,用于延迟创建早期引用
  2. 关键方法getEarlyBeanReference() 处理 AOP 代理
  3. 工作时机:Bean 实例化后、属性注入前
  4. 设计优势
    • 支持 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 主要职责

第三级缓存的三个核心作用:

  1. 延迟创建早期引用
  2. 支持 AOP 代理的特殊处理
  3. 保证 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;
    }
}

两级缓存的问题

  1. 无法处理 AOP 代理:在实例化时无法确定是否需要创建代理
  2. 资源浪费:即使没有循环依赖,也会创建早期引用
  3. 时机不当:在 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;  // 三层循环依赖
}

执行流程

  1. ServiceA 创建

    // 实例化 ServiceA
    // 将 ObjectFactory 放入三级缓存:singletonFactories.put("serviceA", factoryA)
    
  2. ServiceA 注入 ServiceB

    // 触发 ServiceB 的创建
    
  3. ServiceB 创建

    // 实例化 ServiceB  
    // 将 ObjectFactory 放入三级缓存:singletonFactories.put("serviceB", factoryB)
    
  4. ServiceB 注入 ServiceC

    // 触发 ServiceC 的创建
    
  5. ServiceC 创建

    // 实例化 ServiceC
    // 将 ObjectFactory 放入三级缓存:singletonFactories.put("serviceC", factoryC)
    
  6. 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 代理协同工作的核心机制:

核心价值

  1. 延迟创建:只有在真正需要时才创建早期引用
  2. AOP 集成:完美支持代理对象的循环依赖
  3. 资源优化:避免不必要的早期对象创建
  4. 一致性保证:确保所有依赖方使用相同的对象引用

设计哲学

  • 通过 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 第三级缓存的核心价值:

    核心特性:

  1. 延迟决策机制:存储 ObjectFactory 而非具体对象
  2. 动态代理支持:在需要时才决定是否创建代理
  3. AOP 集成:与 BeanPostProcessor 深度集成
  4. 性能优化:避免不必要的代理创建

    设计优势:

  1. 解决循环依赖:为循环依赖提供早期引用
  2. 支持复杂代理场景:处理条件化代理、多层代理等
  3. 保证一致性:确保整个应用中代理对象的一致性
  4. 提供扩展点:通过 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依赖BeanBBeanB又依赖BeanA为例:

  1. 创建BeanA

    • 实例化BeanA(调用构造器),此时BeanA仅为空对象。
    • BeanAObjectFactory存入三级缓存,标记为“正在创建”。
  2. 填充BeanA的属性

    • 发现BeanA依赖BeanB,开始创建BeanB
  3. 创建BeanB

    • 实例化BeanB,将其ObjectFactory存入三级缓存。
    • 填充BeanB的属性时,发现依赖BeanA
  4. 解决BeanB对BeanA的依赖

    • 从一级缓存未找到BeanA,转而从二级缓存查找。
    • 二级缓存未找到,从三级缓存获取BeanAObjectFactory
    • 调用ObjectFactory.getObject()生成BeanA的早期引用(可能是代理对象):
      • BeanA需要AOP增强(如@Transactional),工厂会生成代理对象。
      • 将代理对象存入二级缓存,并从三级缓存移除BeanA的工厂。
    • BeanB注入BeanA的代理对象,完成初始化后存入一级缓存。
  5. 完成BeanA的初始化

    • BeanA从一级缓存获取已初始化的BeanB,完成属性注入。
    • BeanA初始化完成后存入一级缓存,并从二级缓存移除其早期引用。

        三、第三级缓存与AOP的协同机制

  1. 代理对象的延迟生成

    • 三级缓存的工厂对象(ObjectFactory)在生成早期引用时,会通过SmartInstantiationAwareBeanPostProcessor判断是否需要创建代理。
    • 例如,BeanA@Transactional注解标记,工厂会生成其代理对象(如AProxy),而非原始对象。
    • 确保循环依赖中注入的是代理对象,而非可能过期的原始对象。
  2. 避免重复代理

    • 若直接通过二级缓存存储原始对象,当BeanA需要代理时,BeanB会持有原始对象,而最终BeanA会被代理为AProxy,导致BeanB依赖与最终实例不一致。
    • 三级缓存通过工厂动态生成代理,保证所有依赖方获取的是同一实例(原始对象或代理对象)。
  3. 性能优化

    • 仅在发生循环依赖时调用工厂生成代理,避免提前创建不必要的代理对象。
    • 若无循环依赖,工厂不会被触发,Bean会正常初始化并生成代理(如需要),减少性能开销。

        四、第三级缓存的必要性分析

  1. 为何不能仅用二级缓存?

    • 二级缓存存储的是已生成的对象(原始或代理),无法动态决定是否需要代理。
    • BeanA需要代理,但二级缓存中存储的是原始对象,BeanB注入的会是过期引用,导致最终实例不一致。
  2. 三级缓存的“延迟”特性

    • 延迟生成:工厂对象仅在需要时生成实例,避免提前代理的资源浪费。
    • 动态决策:根据Bean是否需要AOP增强,动态返回原始对象或代理对象。

        五、源码关键点解析

  1. 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;
    }
    
  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);
            }
        }
    }
    
  3. 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),提前完成代理操作。

        六、总结:第三级缓存的核心价值

  1. 解决循环依赖与AOP的冲突

    • 通过工厂对象动态生成代理,确保循环依赖中注入的是正确实例。
  2. 性能优化

    • 延迟代理生成,避免不必要的资源消耗。
  3. 线程安全

    • 通过同步块保证多线程环境下缓存的一致性。
  4. 设计精妙性

    • 三级缓存的分层设计(工厂→早期实例→完全实例)完美平衡了灵活性、性能与正确性。

















7️⃣ 参考 7

    Spring第三级缓存详解

        1. 三级缓存的定义与结构 Spring通过三级缓存机制解决单例Bean的循环依赖问题,核心是三个Map容器:

  • 一级缓存(singletonObjects):存储完全初始化完成的单例Bean实例,可直接使用。
  • 二级缓存(earlySingletonObjects):存储提前暴露的“半成品”Bean(已实例化但未属性注入/初始化),用于解决循环依赖。
  • 三级缓存(singletonFactories):存储ObjectFactory(工厂方法),动态生成Bean实例(如AOP代理),是解决循环依赖的关键。

        2. 三级缓存的工作原理 核心流程(以A依赖B、B依赖A的循环依赖为例):

  1. 创建Bean A
    • 实例化A(空对象),将其工厂方法存入三级缓存。
    • 属性注入时发现依赖B,触发B的创建。
  2. 创建Bean B
    • 实例化B,工厂方法存入三级缓存。
    • 属性注入时发现依赖A,从三级缓存获取A的工厂方法。
    • 通过工厂生成A的半成品(若A需AOP则生成代理对象),存入二级缓存并移除三级缓存中的工厂。
    • 将半成品A注入B,完成B的初始化后移入一级缓存。
  3. 完成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注入支持循环依赖,构造器注入不支持。

        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. 核心职责:延迟创建与智能代理

第三级缓存的核心思想是 “不直接存放对象,而是存放创建对象的工厂”。这带来了两个至关重要的优势:

  1. 延迟创建 (Lazy Creation):

    • 在 Bean 实例化完成后,Spring 并不立即将原始对象暴露给其他 Bean。
    • 而是创建一个 ObjectFactory,将其放入三级缓存。这个工厂就像一个“承诺”或“生产指令”,只有当其他 Bean 真正需要这个依赖时,才会触发工厂的 getObject() 方法来创建对象。
    • 这避免了不必要的对象暴露和潜在的资源浪费。
  2. 智能代理 (Smart Proxying):

    • 这是三级缓存存在的根本原因ObjectFactorygetObject() 方法内部会调用 getEarlyBeanReference()
    • getEarlyBeanReference() 会触发 SmartInstantiationAwareBeanPostProcessor 类型的后置处理器,特别是 AbstractAutoProxyCreator(AOP 的核心实现)
    • 在这个阶段,Spring 就能判断当前 Bean 是否需要被 AOP 增强(例如,是否有 @Transactional@Cacheable 等注解)。
    • 如果需要,则在此刻创建代理对象并返回;如果不需要,则返回原始对象

    3. 详细工作流程(结合 AOP)

让我们通过一个具体的例子来理解第三级缓存的生命周期:

场景: ServiceA 依赖 ServiceBServiceB 依赖 ServiceA,且 ServiceA@Transactional 注解。

  1. 创建 ServiceA - 实例化

    • Spring 开始创建 ServiceA
    • 通过构造函数或工厂方法,ServiceA 被实例化(new ServiceA()),此时对象已存在,但属性未注入。
    • 关键步骤: Spring 调用 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
    • 这个 Lambda 表达式 () -> getEarlyBeanReference(...) 就是 ObjectFactory 的核心。
    • 此时,ServiceAObjectFactory 被放入第三级缓存 singletonFactoriesServiceA 的原始对象尚未暴露。
  2. 注入 ServiceA 的依赖 - 创建 ServiceB

    • ServiceA 需要注入 ServiceB,于是 Spring 开始创建 ServiceB
    • ServiceB 经历同样的过程:实例化 → 将其 ObjectFactory 放入第三级缓存。
  3. ServiceB 需要注入 ServiceA (循环依赖点)

    • 当为 ServiceB 注入 ServiceA 时,Spring 调用 getSingleton("serviceA", true)
    • 检查一级缓存(完整Bean)和二级缓存(早期引用)都没有 ServiceA
    • 检查第三级缓存 singletonFactories,发现存在 ServiceAObjectFactory
    • 调用 ObjectFactory.getObject()
    • getObject() 内部执行 getEarlyBeanReference("serviceA", mbd, serviceAInstance)
    • getEarlyBeanReference 遍历 BeanPostProcessor,发现 AbstractAutoProxyCreator
    • AbstractAutoProxyCreator 检查到 ServiceA@Transactional,于是在此刻创建了一个 CGLIB 代理对象 ServiceA$$EnhancerByCGLIB
    • 将这个代理对象返回。
  4. 从第三级缓存“升级”到第二级缓存

    • Spring 将 getEarlyBeanReference 返回的对象(即代理对象)放入第二级缓存 earlySingletonObjects
    • 同时,从第三级缓存 singletonFactories 中移除 ServiceAObjectFactory
    • 这一步非常重要,保证了早期引用只会被创建一次,避免重复代理。
    • 将这个代理对象注入到 ServiceB 中。
  5. 后续流程

    • ServiceB 完成创建,放入一级缓存。
    • ServiceA 继续完成属性注入(注入 ServiceB),执行初始化方法。
    • postProcessAfterInitialization 阶段,AbstractAutoProxyCreator 再次被调用,但它会识别到代理已经创建,直接返回同一个代理对象。
    • 最终,同一个代理对象被放入一级缓存 singletonObjects

    4. 为什么必须是三级?二级缓存为什么不行?

假设没有第三级缓存,只有二级缓存:

  1. ServiceA 实例化后,直接将原始对象放入二级缓存。
  2. ServiceB 从二级缓存拿到的是原始对象
  3. 后续 ServiceA 初始化时,创建了代理对象并放入一级缓存。
  4. 结果
    • 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的流程

  1. Spring开始创建Bean A
  2. 实例化Bean A(此时Bean A是"半成品",属性未注入)
  3. 将Bean A的工厂对象(ObjectFactory)放入第三级缓存
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, singletonFactory));
    
  4. Bean A需要依赖Bean B,于是开始创建Bean B

    2. 创建Bean B的流程

  1. Spring开始创建Bean B
  2. Bean B需要依赖Bean A,于是查找Bean A
  3. 从第三级缓存中获取Bean A的工厂对象
  4. 通过工厂对象生成Bean A的早期引用(可能已应用AOP代理)
  5. 将生成的Bean A早期引用放入第二级缓存(earlySingletonObjects
  6. 从第三级缓存中移除Bean A的工厂对象
  7. Bean B完成初始化,放入第一级缓存(singletonObjects

    3. 回到Bean A的创建

  1. Bean A从第一级缓存获取到完整的Bean B
  2. Bean A完成属性注入和初始化
  3. Bean A放入第一级缓存
  4. 从第二级缓存中移除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的工厂ObjectFactoryBean实例化后,属性注入前提前暴露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;
}

第三级缓存的生命周期

  1. 创建阶段:在Bean实例化后,但属性注入前,将工厂放入第三级缓存
  2. 使用阶段:当其他Bean需要这个Bean的早期引用时,从第三级缓存获取工厂,生成早期Bean
  3. 清理阶段:将生成的早期Bean放入第二级缓存,并从第三级缓存中移除工厂
  4. 完成阶段:当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;
}

在这个例子中:

  1. Spring创建A时,将A的工厂放入第三级缓存
  2. 创建B时,需要A,从第三级缓存获取工厂
  3. 通过工厂生成A的代理对象(已应用AOP)
  4. 将代理对象放入第二级缓存
  5. B完成初始化
  6. A使用B的代理对象,完成初始化

总结

Spring的第三级缓存(singletonFactories)是解决循环依赖和AOP代理问题的关键机制:

  1. 核心功能:存储Bean的工厂对象,用于在Bean创建过程中提前生成Bean的早期引用
  2. 与AOP的关系:确保AOP代理可以在Bean创建的早期阶段生成,避免重复代理
  3. 设计目的:解决循环依赖问题,同时支持AOP代理的提前暴露
  4. 必要性:在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 增强,这里会直接生成代理对象

    为什么需要第三级缓存?

  1. 解决 AOP 代理与循环依赖的冲突
    若没有三级缓存,直接将原始对象放入二级缓存,当 Bean 需要 AOP 增强时,循环依赖注入的会是原始对象,而最终初始化完成的是代理对象,导致不一致。
    三级缓存通过工厂延迟生成代理对象,确保注入的是代理对象(如果需要增强)。

  2. 避免不必要的代理对象生成
    只有当发生循环依赖时,才会通过工厂生成早期引用(可能是代理)。若没有循环依赖,代理对象会在 Bean 完全初始化后生成,符合正常流程。

  3. 支持 SmartInstantiationAwareBeanPostProcessor 扩展
    工厂会触发 SmartInstantiationAwareBeanPostProcessorgetEarlyBeanReference() 方法,允许自定义早期引用的生成逻辑(如 AOP 代理)。

    三级缓存的工作流程(结合循环依赖) 假设场景:Bean A 依赖 Bean B,Bean B 依赖 Bean A,且 A 需要 AOP 增强。

  1. 初始化 A:

    • 实例化 A(调用构造器,未设置属性)
    • 创建 A 的工厂并放入三级缓存:singletonFactories.put("a", () -> getEarlyBeanReference("a", mbd, a))
  2. A 需要注入 B,开始初始化 B:

    • 实例化 B
    • B 需要注入 A,尝试从缓存获取 A:
      • 一级缓存(singletonObjects)无(A 未初始化完成)
      • 二级缓存(earlySingletonObjects)无
      • 从三级缓存获取 A 的工厂,调用 getObject()
        • 触发 AOP 代理生成(因为 A 需要增强)
        • 将生成的 A 代理对象放入二级缓存,同时移除三级缓存中的工厂
  3. B 注入 A 的代理对象后完成初始化,放入一级缓存

  4. 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 对复杂场景的细致处理,是容器初始化过程中的核心环节。



























Spring的三级缓存原理 笔记251008

Spring 如何解决循环依赖 笔记251008

Spring的 三级缓存 与 AOP 笔记251009