Spring单例初始化流程

导读:本篇文章讲解 Spring单例初始化流程,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

概述

Spring的单例对象的初始化主要分为三步。
在这里插入图片描述

  1. createBeanInstance:实例化,其实就是 调用对象的构造方法实例化对象。
  2. populateBean:填充属性,这一步主要是多bean的依赖属性进行填充。
  3. initializeBean:调用spring xml中的init() 方法,或者@PostConstruct注解的init()方法。

三级缓存

对于单例来说,在Spring容器整个生命周期内,有且只有一个对象,所以很容易想到这个对象应该存在Cache中,Spring为了解决单例的循环依赖问题,使用了三级缓存。

哪三级缓存

/** Cache of singleton objects: bean name --> bean instance */
// 一级缓存,完全初始化好的单例放入其中,从上下文获取的单例就是从这里获取
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
/** Cache of singleton factories: bean name --> ObjectFactory */
// 三级缓存,存放实例化的对象,还没有对其进行属性填充
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/** Cache of early singleton objects: bean name --> bean instance */
// 二级缓存,提前暴光的单例对象的Cache(用于检测循环引用,与singletonFactories互斥,就是要么在singletonFactories中要么在earlySingletonObjects中),
// 也只是实例化,但还没有填充属性
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

从缓存中获取bean

在获取bean的时候,首先是根据beanName从缓存中获取bean,如果获取不到就通过单列工厂创建,具体的流程可以看单列初始化流程图。
缓存中获取bean的逻辑是先从singletonObjects(一级缓存)获取,如果获取不到去earlySingletonObjects(二级缓存)获取,还是获取不到就从singletonFactories(三级缓存)获取。
源码如下:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            Map var4 = this.singletonObjects;
            synchronized(this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject != NULL_OBJECT ? singletonObject : null;
    }

注释

  1. isSingletonCurrentlyInCreation()判断当前单例bean是否正在创建中,
    也就是没有初始化完成(比如A的构造器依赖了B对象所以得先去创建B对象,
    或则在A的populateBean过程中依赖了B对象,得先去创建B对象,这时的A就是处于创建中的状态。)
  2. allowEarlyReference 是否允许从singletonFactories中通过getObject拿到对象。

单例初始流程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/100357.html

(0)
小半的头像小半

相关推荐

半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!