Spring 三级缓存

简介

package org.springframework.beans.factory.support;

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    /** Cache of singleton objects: bean name to bean instance. */
    private final Map singletonObjects = new ConcurrentHashMap<>(256);

    /** Cache of singleton factories: bean name to ObjectFactory. */
    private final Map> singletonFactories = new HashMap<>(16);

    /** Cache of early singleton objects: bean name to bean instance. */
    private final Map earlySingletonObjects = new ConcurrentHashMap<>(16);
}
  • singletonObjects:一级缓存,调用 getBean() 可以直接获取初始化完成的 单例对象。
  • earlySingletonObjects:二级缓存,已经被 AOP 增强,但是还有属性没有注入完。
  • singletonFactories:遍历所有的 BeanPostProcessor 后置处理器,通过 SmartInstantiationAwareBeanPostProcessor 类型的后置处理器进行 AOP 增强。

缓存初始化时机

  • singletonFactories:实例化对象(createBeanInstance 方法)之后,填充属性(populateBean 方法)之前。
    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
        // 1. 实例化 Bean 对象
        BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
        
        // 2. 把用 lambda 表达式 表示的 ObjectFactory,添加到 singletonFactories 缓存
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        
        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            // 3. 填充 Bean 对象的属性  
            populateBean(beanName, mbd, instanceWrapper);
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        return exposedObject;
    }
  • earlySingletonObjects:存在循环引用时才会初始化。在 getSingleton() 方法中,通过 singletonFactories 获取到 AOP 对象后填入。
    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) {
                    // 1. 获取到 ObjectFactory 缓存
                    ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        // 2. 通过 `getEarlyBeanReference()` 方法得到 AOP 增强的代理对象
                        singletonObject = singletonFactory.getObject();

                        // 3. 将 AOP 增强的代码对象存放到 earlySingletonObjects 缓存中
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }
  • singletonObjects:单例对象 初始化完成(属性填充完毕,以及执行完所有的 Spring 初始化生命周期方法后)填入。

参考

  • 跳出源码地狱,Spring 巧用三级缓存解决循环依赖-原理篇

你可能感兴趣的:(Spring 三级缓存)