从源码出发,一文读懂 Bean 的初始化流程及三级缓存机制

spring 通过三级缓存来解决 Bean 的循环依赖问题,该机制的相关代码主要位于DefaultSingletonBeanRegistry 类中。下面将从该类的源码出发,重新学习三级缓存机制。

注意:三级缓存机制只能解决 setter 注入的循环依赖问题,如果是构造器注入的方式,使用反射的方式进行注入,用三级缓存也是不能解决循环依赖问题的。本文针对的也是 setter 注入造成的循环依赖问题。

一、Bean 对象初始化入口

AbstractApplicationContext 类的 refresh() 方法

AbstractApplicationContext 类的 refresh() 方法是 Spring 容器启动和刷新的核心方法,它会完成一系列重要操作,包括 Bean 定义的加载、Bean 工厂的初始化、Bean 的创建等。

对于非懒加载的单例 Bean,Spring 容器会在 AbstractApplicationContext 的 refresh() 方法执行期间,具体是在 finishBeanFactoryInitialization 步骤中,通过 beanFactory.preInstantiateSingletons() 方法对它们进行提前初始化,确保这些 Bean 在容器启动时就已经创建并初始化完成。

注意到,在进行单例的提前初始化之前,调用了this.registerBeanPostProcessors(beanFactory) 来进行类后处理器的注册。比如说负责处理 AOP 动态增强的类后处理器 AnnotationAwareAspectJAutoProxyCreator就是在这里注册的,确保了未来进行单例初始化时得到的是增强后的单例

public void refresh() throws BeansException, IllegalStateException {  
    synchronized(this.startupShutdownMonitor) {  
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");  
        this.prepareRefresh();  
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();  
        this.prepareBeanFactory(beanFactory);  

        try {  
            this.postProcessBeanFactory(beanFactory);  
            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");  
            this.invokeBeanFactoryPostProcessors(beanFactory);  
            // 注册类后处理器
            this.registerBeanPostProcessors(beanFactory);  
            beanPostProcess.end();  
            this.initMessageSource();  
            this.initApplicationEventMulticaster();  
            this.onRefresh();  
            this.registerListeners();  
            // 实例化所有剩余的(非懒加载的单例)Bean
            this.finishBeanFactoryInitialization(beanFactory);  
            this.finishRefresh();  
        } catch (BeansException var10) {  
            if (this.logger.isWarnEnabled()) {  
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);  
            }  

            this.destroyBeans();  
            this.cancelRefresh(var10);  
            throw var10;  
        } finally {  
            this.resetCommonCaches();  
            contextRefresh.end();  
        }  

    }  
}

// 先注册类后处理器
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {  
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);  
}

// 提前初始化单例(without @LazyInit)
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {  
    ......
    // 提前初始化单例
    beanFactory.preInstantiateSingletons();  
}

二、提前初始化单例

在上部分中提到的 beanFactory.preInstantiateSingletons() 方法是接口 ConfigurableListableBeanFactory 接口提供的,其具体实现在 DefaultListableBeanFactory 类里。

在 Spring 框架中,DefaultListableBeanFactory 是该接口的一个重要实现类。DefaultListableBeanFactory 功能强大,它综合了 ListableBeanFactoryAutowireCapableBeanFactoryConfigurableBeanFactory 等多个接口的能力,是 Spring 容器中完成 Bean 管理工作的核心类之一。

其提供的 preInstantiateSingletons() 方法核心功能是遍历 beanDefinitionNames,依次进行实例化。

源码分析 beanFactory.preInstantiateSingletons()

1 使用迭代器 var2 遍历 beanNames 列表。
2 对于每个 BeanName,获取其合并后的 BeanDefinition bd
3 通过多层 do-while 循环筛选出非抽象、单例且非懒加载的 Bean。调用getBean()进行实例化。

  • 如果是 FactoryBean 类型的 Bean,通过在 Bean 名称前加 & 符号调用 getBean() 方法获取 FactoryBean 实例本身。
  • 如果不是 FactoryBean,直接调用 getBean() 方法进行实例化。

这里这个多层的 do-while 循环的过滤模式值得学习一下

public void preInstantiateSingletons() throws BeansException {  
    if (this.logger.isTraceEnabled()) {  
        this.logger.trace("Pre-instantiating singletons in " + this);  
    }  
    // 1 使用迭代器 var2 遍历 beanNames 列表
    List<String> beanNames = new ArrayList(this.beanDefinitionNames);  
    Iterator var2 = beanNames.iterator();  

    while(true) {  
        String beanName;  
        Object bean;  
        do {  
            while(true) {  
                RootBeanDefinition bd;  
                // 跳过抽象的bd
                do {  
                    // 过滤原型
                    do {  
                        // 过滤懒加载
                        do {  
                            if (!var2.hasNext()) {  
                                // 这里是所有的 bean 都处理完(迭代器空),进入后续的 SmartInitializingSingleton 处理阶段
                                var2 = beanNames.iterator();  

                                while(var2.hasNext()) {  
                                    beanName = (String)var2.next();  
                                    // ⚠️ 调用 DefaultSingletonBeanRegistry 的 getSingleton() 在这里面进行三级缓存!!!
                                    Object singletonInstance = this.getSingleton(beanName);  
                                    if (singletonInstance instanceof SmartInitializingSingleton) {  
                                        StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);  
                                        SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;  
                                        if (System.getSecurityManager() != null) {  
                                            AccessController.doPrivileged(() -> {  
                                                smartSingleton.afterSingletonsInstantiated();  
                                                return null;  
                                            }, this.getAccessControlContext());  
                                        } else {  
                                            smartSingleton.afterSingletonsInstantiated();  
                                        }  

                                        smartInitialize.end();  
                                    }  
                                }  

                                return;  
                            }  

                            beanName = (String)var2.next();  
                            bd = this.getMergedLocalBeanDefinition(beanName);  
                        // 是抽象的跳过
                        } while(bd.isAbstract());  
                    // 不是单例的跳过
                    } while(!bd.isSingleton());  
                // 懒加载的跳过
                } while(bd.isLazyInit());  

                // 筛选出 非抽象的、非懒加载的单例 Bean
                if (this.isFactoryBean(beanName)) {  
                    bean = this.getBean("&" + beanName);  
                    // 跳出 while(true)
                    break;  
                }  
                //  如果是非工厂调用 getBean(beanName) 进行实例化 
                this.getBean(beanName);  
            }// true while
        } while(!(bean instanceof FactoryBean));

        // 直到找到的 Bean 是 FactoryBean 类型
        FactoryBean<?> factory = (FactoryBean)bean;  
        boolean isEagerInit;  
        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {  
            SmartFactoryBean var10000 = (SmartFactoryBean)factory;  
            ((SmartFactoryBean)factory).getClass();  
            isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());  
        } else {  
            isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();  
        }  

        if (isEagerInit) {  
            this.getBean(beanName);  
        }  
    }  
}

@Nullable  
public Object getSingleton(String beanName) {  
    // allowEarlyReference:true 可能返回二级缓存中的,来解决循化依赖
    return this.getSingleton(beanName, true);  
}

public Object getBean(String name) throws BeansException {  
    return this.doGetBean(name, (Class)null, (Object[])null, false);  
}

其中涉及到的两个核心方法:AbstractBeanFactorydoGetBean() 和 接口 SingletonBeanRegistry 提供的的 getSingleton()

其中doGetBean() 是 Spring Bean 工厂中创建和获取 Bean 实例的核心方法,当 doGetBean() 处理单例 Bean 时,会先调用 getSingleton() 检查缓存。若 Bean 不存在,doGetBean() 会通过 createBean() 实例化 Bean,并在创建过程中再次调用 getSingleton() 注册单例

也就是说,二者的关系是:

  • doGetBean() 负责 Bean 的整体生命周期(实例化、依赖注入、初始化)。
  • getSingleton() 专注于单例 Bean 的缓存和线程安全创建,是 doGetBean() 在处理单例时的底层支撑。

三、AbstractBeanFactory.doGetBean()

下面提炼出一些相关的核心代码如下:

在阅读这部分源码时,注意下面几点:

  • 在代码 2 部分中,是对 depends-on 强依赖关系进行的初始化,它要求在创建当前 Bean 之前,必须先创建其依赖的 Bean。这种依赖如果发生循环依赖会直接抛异常!
protected <T> T doGetBean(
        String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
        throws BeansException {
    String beanName = this.transformedBeanName(name);  
    //  1 调用 getSingleton() ,尝试在三级缓存中获取 见 三.A 部分 
    Object sharedInstance = this.getSingleton(beanName, true);  
    Object beanInstance;  
    if (sharedInstance != null && args == null) {
        ......
        // 1.1 若从缓存中获取到 Bean 实例,进行一些处理返回
        beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
        // 1.2 若没有从缓存中获取到,准备创建新的 Bean 实例
        // 2.1 获取并验证 Bean 的元数据
        RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
        this.checkMergedBeanDefinition(mbd, beanName, args);
        // 2.2 获取强依赖 Bean 的元数据,这里是 depends-on 关系的强依赖,如果发生循环依赖是解决不了的!!!
        String[] dependsOn = mbd.getDependsOn();
        if (dependsOn != null) {
            for (String dep : dependsOn) {
                if (isDependent(beanName, dep)) {
                    // 2.2.1 如果发现循环依赖,抛出异常
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                }
                //  2.2.2 在依赖关系 map 中注册该依赖关系
                registerDependentBean(dep, beanName);
                try {
                    //  2.2.3 这里是调用依赖 Bean 的 getBean,注意现在在走的这个方法就是目标 Bean 的 getBean,所以这里会对依赖 Bean 进行构造!
                    getBean(dep);
                } catch (NoSuchBeanDefinitionException ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                }
            }
        }
        // 2.3 强依赖的 Bean 单例构造完成
        // 3 目标 Bean 单例生命周期开走!
        if (mbd.isSingleton()) {  
            // 调用 getSingleton(beanName, beanFactory);
            sharedInstance = this.getSingleton(beanName, () -> {  
                try {  
                    return this.createBean(beanName, mbd, args);  
                } catch (BeansException var5) {  
                    this.destroySingleton(beanName);  
                    throw var5;  
                }  
            });  
        } else {
            ......
        }   
    }
    ......
    return (T) beanInstance;
}

注意,在 AbstractBeanFactory 处理单例 Bean 时,会调用其父类 DefaultSingletonBeanRegistry 提供的 getSingleton(beanName, singletonFactory),其参数 singletonFactory 会调用抽象方法 createBean() 得到 Bean 对象,这个抽象方法的具体实现类在其子类 AbstractAutowireCapableBeanFactory 中。

 A. getSingleton() 方法处理单例缓存

在 doGetBean() 方法中,会调用 DefaultSingletonBeanRegistry 类的 getSingleton() 方法来处理单例缓存。如果缓存中没有该 Bean 实例,则会调用传入的 ObjectFactory 来创建 Bean 实例。

protected Object getSingleton(String beanName, boolean allowEarlyReference) {  
    Object singletonObject = this.singletonObjects.get(beanName);  
    // 1 一级缓存没有,且正处于创建中状态
    if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {  
        // 2 尝试在二级缓存获取
        // earlySingletonObjects 存储的是已经实例化但还未完全初始化的单例 Bean 的早期引用
        singletonObject = this.earlySingletonObjects.get(beanName);  
        if (singletonObject == null && allowEarlyReference) {  
            // 尝试获取锁 :防止多个线程同时操作缓存,确保在多线程环境下数据的一致性
            synchronized(this.singletonObjects) {  
                // 双重检查机制 再次检查一级二级缓存
                singletonObject = this.singletonObjects.get(beanName);  
                if (singletonObject == null) {  
                    singletonObject = this.earlySingletonObjects.get(beanName);  
                    if (singletonObject == null) {  
                        // 3 从三级缓存(singletonFactories)中获取该 Bean 的单例工厂
                        // singletonFactories 存储的是创建单例 Bean 的工厂
                        ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);  
                        if (singletonFactory != null) {  
                            // 4 如果三级缓存有保存,那么从单例工厂生产 Bean 的前期引用,加入二级缓存,从三级缓存中移除
                            singletonObject = singletonFactory.getObject();  
                            this.earlySingletonObjects.put(beanName, singletonObject);  
                            this.singletonFactories.remove(beanName);  
                        }  
                    }  
                }  
            }  
        }  
    }  
    // 5 返回单例(如果 allowEarlyReference 为 true 可能返回的是前期对象,用于避免循环依赖)
    return singletonObject;  
}

getSingleton(beanName, singletonFactory 的作用是如果一级缓存中存在就直接返回,否则就调用 singletonFactory 进行创建。

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {  
    Assert.notNull(beanName, "Bean name must not be null");  
    synchronized(this.singletonObjects) {  
        //  1 尝试一级缓存获取
        Object singletonObject = this.singletonObjects.get(beanName);  
        if (singletonObject == null) {  
            // 1 一级缓存没有,也就是没有还没有进行初始化注册
            if (this.singletonsCurrentlyInDestruction) {  
                // 该状态为了标识是否在进行销毁,该状态下不允许创建
                throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");  
            }  

            if (this.logger.isDebugEnabled()) {  
                this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");  
            }  

            // 2 将 beanName 加入到正在创建的单例名称 set singletonsCurrentlyInCreation
            this.beforeSingletonCreation(beanName);  
            boolean newSingleton = false;  
            boolean recordSuppressedExceptions = this.suppressedExceptions == null;  
            if (recordSuppressedExceptions) {  
                this.suppressedExceptions = new LinkedHashSet();  
            }  

            try {  
                // 3 调用传入的 singletonFactory 的 getObject()创建 Bean
                singletonObject = singletonFactory.getObject();  
                newSingleton = true;  
            } catch (IllegalStateException var16) {  
                singletonObject = this.singletonObjects.get(beanName);  
                if (singletonObject == null) {  
                    throw var16;  
                }  
            } catch (BeanCreationException var17) {  
                BeanCreationException ex = var17;  
                if (recordSuppressedExceptions) {  
                    Iterator var8 = this.suppressedExceptions.iterator();  

                    while(var8.hasNext()) {  
                        Exception suppressedException = (Exception)var8.next();  
                        ex.addRelatedCause(suppressedException);  
                    }  
                }  

                throw ex;  
            } finally {  
                if (recordSuppressedExceptions) {  
                    this.suppressedExceptions = null;  
                }  

                this.afterSingletonCreation(beanName);  
            }  
            // 4 将新创建的 Bean 加入一级缓存 
            if (newSingleton) {  
                this.addSingleton(beanName, singletonObject);  
            }  
        }  

        return singletonObject;  
    }  
}

B. createBean() 方法创建 Bean 实例

在 getSingleton() 方法中调用的 ObjectFactory 会调用 AbstractAutowireCapableBeanFactory 类的 createBean() 方法来创建 Bean 实例。

值得注意的是,会在 Bean 单例实例化之前给一个调用类后处理器的机会,比如 AOP 增强就在这里插入,使得 singletonFactory 得到的可能是一个代理对象。

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    RootBeanDefinition mbdToUse = mbd;

    // 解析 Bean 类
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // 准备方法覆盖
    try {
        mbdToUse.prepareMethodOverrides();
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }

    try {
        // 给 BeanPostProcessor 一个机会来返回一个代理而不是目标 Bean 实例
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    } catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                "BeanPostProcessor before instantiation of bean failed", ex);
    }

    try {
        // 实际创建 Bean 实例
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        throw ex;
    } catch (Throwable ex) {
        throw new BeanCreationException(
                mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}

 C. doCreateBean() 方法完成 Bean 初始化

createBean() 方法会调用 doCreateBean() 方法,该方法会完成 Bean 的实例化、属性注入和初始化操作。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    // 1. 反射 实例化 Bean 
    BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
    Object bean = instanceWrapper.getWrappedInstance();

    // 2. 允许提前暴露单例 Bean 以解决循环依赖
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        // 3. 先添加 singletonFactory 到三级缓存当中
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // 4. 填充 Bean 属性
    populateBean(beanName, mbd, instanceWrapper);

    // 5. 初始化 Bean
    Object exposedObject = initializeBean(beanName, bean, mbd);

    return exposedObject;
}

附1:接口 SingletonBeanRegistry

DefaultSingletonBeanRegistry 是 Spring 核心接口 SingletonBeanRegistry 的具体实现类。SingletonBeanRegistry 接口为 Spring 容器提供了管理单例 Bean 的基本能力,它使得 Spring 能够集中管理单例 Bean 的注册、获取和查询等操作。抽象出了下面几种 Bean 管理方法:

  1. registerSingleton(String beanName, Object singletonObject)
    • 该方法用于向注册表中注册一个新的单例 Bean。beanName 是要注册的 Bean 的名称,singletonObject 是单例 Bean 的实例。如果指定的 beanName 已经存在于注册表中,会抛出 IllegalStateException 异常。
  2. getSingleton(String beanName)
    • 根据 beanName 从注册表中获取单例 Bean 的实例。如果指定名称的单例 Bean 存在,则返回其实例;否则返回 null
  3. containsSingleton(String beanName)
    • 检查注册表中是否包含指定名称的单例 Bean。如果包含则返回 true,否则返回 false
  4. getSingletonNames()
    • 获取注册表中所有单例 Bean 的名称,并以数组的形式返回。
  5. getSingletonCount()
    • 获取注册表中当前单例 Bean 的数量。
  6. getSingletonMutex()
    • 获取用于同步单例访问的对象,通常用于确保在多线程环境下对单例 Bean 的安全访问。

附2 : 具体实现 DefaultSingletonBeanRegistry

DefaultSingletonBeanRegistry 作为 SingletonBeanRegistry 接口的实现,负责了容器中单例 Bean 的生命周期,具体而言,它提供了以下功能:

  • 存储单例 Bean
  • 提供单例 Bean 的注册功能
  • 负责单例 Bean 的销毁
  • 提供获取单例 Bean 的功能

核心字段

类型一 单例 Bean 的状态储存

Bean 单例名称储存(按注册顺序)

用一个 LinkedHashSet 类型来保存所有已经注册的单例 Bean 的名称,该数据结构决定了能够保证 Bean 的注册顺序。(LinkedHashSet 类似于 LRU 缓存,HashMap + 双向链表)。

private final Set<String> registeredSingletons = new LinkedHashSet(256);
// 保存注册了销毁的 Bean 单例
private final Map<String, Object> disposableBeans = new LinkedHashMap();
Bean 单例之间关系的储存

用三个 set 分别保存 Bean 单例之间的包含、依赖以及被依赖关系,这些关系在以后进行 Bean 的销毁时意义重大!

private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap(16);  
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap(64);  
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap(64);

类型二 注册 Bean 单例相关

而实际注册好的 Bean 单例保存在 singletonObjects,这是一个 ConcurrentHashMap,键为 Bean 的名称,值为对应的 Bean 实例。同时这也是三级缓存的最高级缓存!

private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);  

为了一定程度上解决循环依赖问题,spring 采用了三级缓存的机制,每一级缓存实际上都是一个 Map 结构,如下:

// 二级缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);  
// 三级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);  
  • singletonFactories
    • 这是一个 HashMap,属于三级缓存,用于存储创建单例 Bean 的工厂。键为 Bean 的名称,值为 ObjectFactory 实例,借助该工厂能够获取早期的单例 Bean
  • earlySingletonObjects
    • 这是一个 ConcurrentHashMap,属于二级缓存,用于存储已经实例化但还未完全初始化的单例 Bean。键为 Bean 的名称,值为对应的 Bean 实例。

关于具体的三级缓存机制代码将在下部分详细讲解。

类型三 Bean 单例创建状态相关

private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap(16));  
private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap(16));

这是两个 Set 结构的字段,其中 singletonsCurrentlyInCreation 用于记录当前正在处于创建状态的单例 Bean 的名称

附3: 功能实现详解

明确了该类的数据结构后,我们从几大核心方法出发来学习 Spring 是如何实现 SingletonBeanRegistry 接口需要提供的功能的:

1 registerSingleton()

该方法用于注册单例,注意到入参是 beanNamesingletonObject,因此在调用 registerSingleton 的时候,bean 单例已经被创建完成了。因此删除二级、三级缓存中的对象,加入一级缓存进行管理。

public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {  
    Assert.notNull(beanName, "Bean name must not be null");  
    Assert.notNull(singletonObject, "Singleton object must not be null");  
    synchronized(this.singletonObjects) {  
        // 避免重复注册
        Object oldObject = this.singletonObjects.get(beanName);  
        if (oldObject != null) {  
            throw new IllegalStateException("Could not register object [" + singletonObject + "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");  
        } else {  
            // 注册
            this.addSingleton(beanName, singletonObject);  
        }  
    }  
}  

protected void addSingleton(String beanName, Object singletonObject) {  
    synchronized(this.singletonObjects) {  
        this.singletonObjects.put(beanName, singletonObject);  、
        // 移除 二级、三级缓存
        this.singletonFactories.remove(beanName);  
        this.earlySingletonObjects.remove(beanName); 
        // 将已经完成初始化的 Bean 单例加入到状态管理中 
        this.registeredSingletons.add(beanName);  
    }  
}

既然 registerSingleton 注册 Bean 是在初始化完成 Bean 之后调用,那实际进行 Bean 初始化的代码在哪里呢?

实际上,DefaultSingletonBeanRegistry 类中的 getSingleton 方法用于从单例缓存中获取 Bean 实例,如果不存在则调用传入的 ObjectFactory 创建 Bean。因此创建 Bean 的代码在 getSingleton 方法中。

getSingleton()

@Nullable  
protected Object getSingleton(String beanName, boolean allowEarlyReference) {  
    Object singletonObject = this.singletonObjects.get(beanName);  
    // 1 一级缓存没有,且正处于创建中状态
    if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {  
        // 2 尝试在二级缓存获取
        // earlySingletonObjects 存储的是已经实例化但还未完全初始化的单例 Bean 的早期引用
        singletonObject = this.earlySingletonObjects.get(beanName);  
        if (singletonObject == null && allowEarlyReference) {  
            // 尝试获取锁 :防止多个线程同时操作缓存,确保在多线程环境下数据的一致性
            synchronized(this.singletonObjects) {  
                // 双重检查机制 再次检查一级二级缓存
                singletonObject = this.singletonObjects.get(beanName);  
                if (singletonObject == null) {  
                    singletonObject = this.earlySingletonObjects.get(beanName);  
                    if (singletonObject == null) {  
                        // 3 从三级缓存(singletonFactories)中获取该 Bean 的单例工厂
                        // singletonFactories 存储的是创建单例 Bean 的工厂
                        ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);  
                        if (singletonFactory != null) {  
                            // 4 从单例工厂生产 Bean 的前期引用,加入二级缓存,从三级缓存中移除
                            singletonObject = singletonFactory.getObject();  
                            this.earlySingletonObjects.put(beanName, singletonObject);  
                            this.singletonFactories.remove(beanName);  
                        }  
                    }  
                }  
            }  
        }  
    }  
    // 5 返回单例(如果 allowEarlyReference 为 true 可能返回的是前期对象,用于避免循环依赖)
    return singletonObject;  
}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {  
    Assert.notNull(beanName, "Bean name must not be null");  
    synchronized(this.singletonObjects) {  
        //  1 尝试一级缓存获取
        Object singletonObject = this.singletonObjects.get(beanName);  
        if (singletonObject == null) {  
            // 1 一级缓存没有,也就是没有还没有进行初始化注册
            if (this.singletonsCurrentlyInDestruction) {  
                // 该状态为了标识是否在进行销毁,该状态下不允许创建
                throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");  
            }  

            if (this.logger.isDebugEnabled()) {  
                this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");  
            }  

            // 2 将 beanName 加入到正在创建的单例名称 set singletonsCurrentlyInCreation
            this.beforeSingletonCreation(beanName);  
            boolean newSingleton = false;  
            boolean recordSuppressedExceptions = this.suppressedExceptions == null;  
            if (recordSuppressedExceptions) {  
                this.suppressedExceptions = new LinkedHashSet();  
            }  

            try {  
                // 3 调用传入的 singletonFactory 的 getObject()创建 Bean
                singletonObject = singletonFactory.getObject();  
                newSingleton = true;  
            } catch (IllegalStateException var16) {  
                singletonObject = this.singletonObjects.get(beanName);  
                if (singletonObject == null) {  
                    throw var16;  
                }  
            } catch (BeanCreationException var17) {  
                BeanCreationException ex = var17;  
                if (recordSuppressedExceptions) {  
                    Iterator var8 = this.suppressedExceptions.iterator();  

                    while(var8.hasNext()) {  
                        Exception suppressedException = (Exception)var8.next();  
                        ex.addRelatedCause(suppressedException);  
                    }  
                }  

                throw ex;  
            } finally {  
                if (recordSuppressedExceptions) {  
                    this.suppressedExceptions = null;  
                }  

                this.afterSingletonCreation(beanName);  
            }  
            // 4 将新创建的 Bean 加入一级缓存 
            if (newSingleton) {  
                this.addSingleton(beanName, singletonObject);  
            }  
        }  

        return singletonObject;  
    }  
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇