美文网首页
Spring 三级缓存

Spring 三级缓存

作者: 蓝笔头 | 来源:发表于2022-02-22 12:56 被阅读0次

    简介

    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<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    
        /** Cache of singleton factories: bean name to ObjectFactory. */
        private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    
        /** Cache of early singleton objects: bean name to bean instance. */
        private final Map<String, Object> 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 三级缓存

          本文链接:https://www.haomeiwen.com/subject/iolglrtx.html