Spring5源码分析(023)——IoC篇之bean加载:从缓存中获取单例 bean

注:《Spring5源码分析》汇总可参考:Spring5源码分析(002)——博客汇总


  介绍完 FactoryBean 的小知识之后,我们就可以了解 bean 加载的过程了。前面提到过 bean 加载过程中首先会获取真正的 beanName (前面的文章已分析过),然后再通过 beanName 从单例缓存中尝试获取单例 bean ,本篇将就“从缓存中获取单例 bean”这一步进行讲解,其调用代码如下:
/// org.springframework.beans.factory.support.AbstractBeanFactory

// Eagerly check singleton cache for manually registered singletons.
/*
 * 2、从缓存或者实例工厂中获取单例 bean 对象:检查缓存中或者实例工厂中是否有对应的 bean 实例
 * 为什么需要使用这段代码,来检查缓存?
 * 因为在创建单例 bean 的时候会存在依赖注入的情况,而在创建依赖的时候为了避免依赖循环,
 * Spring 创建 bean 的原则是不等 bean 创建完成就会将创建 bean 的 ObjectFactory 提前曝光,
 * 也就是将 ObjectFactory 加入到缓存中,一旦下个 bean 创建时需要依赖上个 bean 则直接使用 ObjectFactory
 */
// 检查注册的单例缓存中是否有对应的单例
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
    if (logger.isTraceEnabled()) {
        if (isSingletonCurrentlyInCreation(beanName)) {
            logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                    "' that is not fully initialized yet - a consequence of a circular reference");
        }
        else {
            logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
        }
    }
    // 返回对应的实例,有时候存在诸如 FactoryBean 的情况下,可能返回 FactoryBean 本身,
    // 也有可能返回的是 FactoryBean 指定方法返回的实例
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

  本文目录结构如下:

 

1、getSingleton

  前面提到过,单例在 Spring 的同一个容器内只会被创建一次,后续再获取 bean 时会直接从单例缓存中获取。当然,这里也只是尝试加载,首先尝试从单例缓存 singletonObjects 中加载,然后再次尝试从 earlySingletonObjects 中加载,之后再尝试从 singletonFactories 中获取,因为在创建单例 bean 的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring 创建 bean 的原则是不等 bean 创建完成就会将创建 bean 的 ObjectFactory 提早曝光加入到缓存中,一旦下一个 bean 创建时需要依赖上个 bean ,则直接使用 ObjectFactory。 AbstractBeanFactory#getSingleton(String beanName) 方法就是处理的这事,其内部代码如下:
/// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

@Override
@Nullable
public Object getSingleton(String beanName) {
    // 参数 allowEarlyReference 标识设置为 true 表示允许提前依赖引用
    return getSingleton(beanName, true);
}

/**
 * Return the (raw) singleton object registered under the given name.
 * <p>Checks already instantiated singletons and also allows for an early
 * reference to a currently created singleton (resolving a circular reference).
 * <p>返回在给定名称下注册的(原始)单例对象
 * <p>检查已实例化的单例,并允许提前引用当前正在创建中的单例(解析循环引用)。
 * @param beanName the name of the bean to look for
 * @param allowEarlyReference whether early references should be created or not
 * @return the registered singleton object, or {@code null} if none found
 */
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 检查单例缓存中是否存在实例
    Object singletonObject = this.singletonObjects.get(beanName);
    // 如果为空,并且该 bean 正在创建中
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        // 加锁,锁住 singletonObjects 全局变量并进行处理
        synchronized (this.singletonObjects) {
            // 从 earlySingletonObjects 中获取
            // 如果该 bean 正在加载则不处理
            // 因为单例 singleton 是复用以前的创建的 bean ,因此需要检查是否已创建或者创建中
            singletonObject = this.earlySingletonObjects.get(beanName);
            // 只有 earlySingletonObjects 中不存在且允许提前创建,才会进行 singleton bean 的实例化
            if (singletonObject == null && allowEarlyReference) {
                // 从 singletonFactories 中获取对应的 ObjectFactory
                // 当某些方法需要提前初始化的时候会调用 addSingletonFactory 方法将对应的
                // ObjectFactory 初始化策略存储在 singletonFactories 中
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    // 调用预先设定的 getObject 方法获得 bean
                    singletonObject = singletonFactory.getObject();
                    // 记录在缓存中, earlySingletonObjects 和 singletonFactories 互斥
                    // 添加 bean 到 earlySingletonObjects 中
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    // 从 singletonFactories 移除对应的 ObjectFactory
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}
  这个方法涉及到循环依赖的检测,其中又涉及到很多变量的记录存取,而这些变量则是解决循环依赖的关键所在。初看可能会觉得很绕口、很复杂,保持蛋定,莫慌,这段代码只是通过几个变量来判断完成,逻辑上还是比较简洁的,上面这个判断过程整理如下:
  • 第一步,首先尝试从单例缓存 singletonObjects 里面获取 bean 实例对象。
  • 第二步,如果获取不到,则再从 earlySingletonObjects 里面获取。
  • 第三步,如果还获取不到,且允许提前创建,则尝试从 singletonFactories 里面获取 beanName 对应的 ObjectFactory ,若不为空则调用 ObjectFactory#getObject() 来创建 bean ,然后放到 earlySingletonObjects 里面去,并且从 singletonFactories 里面删除掉 ,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在 allowEarlyReference 为 true 的情况下才会使用。
  这块的总体逻辑就是,检测与 beanName 有关的三个 Map ,如果为空,依次获取,否则返回,而这三个 Map 存储的 bean 都有各自的功能,这是解决循环依赖的关键所在,具体的说明如下:
/// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

/**
 * Cache of singleton objects: bean name to bean instance.
 * <p>单例 bean 实例对象的缓存映射: beanName --> bean 实例。
 * <p>保存实例化、初始化都完成的单例 bean 对象,称为【一级缓存】
 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/**
 * Cache of singleton factories: bean name to ObjectFactory.
 * <p>单例 Factory 缓存(创建 bean 的工厂)映射: beanName --> ObjectFactory。
 * <p>保存对象工厂 ObjectFactory ,用于创建二级缓存中的对象,称为【三级缓存】
 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/**
 * Cache of early singleton objects: bean name to bean instance.
 * <p>单例 bean 实例对象的缓存: beanName --> bean 实例。
 * <p>保存实例化完成、但是未初始化完成的提前曝光的对象,即早期的 bean ,称为【二级缓存】
 * <p>与 {@link #singletonObjects }的区别在于其存放的 bean 不一定是完整的,
 * 而从{@link #getSingleton(String) }中可以看到 bean 创建过程中就直接加入到 earlySingletonObjects
 * 中了,所以才可以通过 getBean 获取创建过程中的 bean ,这也是解决【循环依赖】 的关键所在
 */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
 

1.1、isSingletonCurrentlyInCreation(String beanName)

  这里也不要漏掉一个同样很重要的检测方法 isSingletonCurrentlyInCreation(String beanName) ,这个方法主要是判断该 beanName 对应的 bean 是否在创建中,代码如下:
/// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

/**
 * Names of beans that are currently in creation.
 * <p>当前正在创建中的 beans 的 beanName 集合
 */
private final Set<String> singletonsCurrentlyInCreation =
        Collections.newSetFromMap(new ConcurrentHashMap<>(16));

/**
 * Return whether the specified singleton bean is currently in creation
 * (within the entire factory).
 * <p>返回指定的单例bean当前是否正在创建(在整个 beanFactory 内)。
 * @param beanName the name of the bean
 */
public boolean isSingletonCurrentlyInCreation(String beanName) {
    return this.singletonsCurrentlyInCreation.contains(beanName);
}

  结合前面提到的,首先需要获取是否有已经实例化完整的 bean ,如果没有而且允许提前创建,这个时候才会去查找创建过程中的 bean 。因此可以猜到,bean 创建过程中都会加入到 singletonsCurrentlyInCreation 集合中,这样就知道哪些在创建中可以提前返回引用了,否则就很难判断实例化过程中的循环依赖了。至于创建过程中是在哪里、什么时候加的,后面会分析到。(注:后面 DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory) 中的创建前的前置处理中默认会用到)

 

2、getObjectForBeanInstance

  在 getBean 方法中, getObjectForBeanInstance 是个高频使用的方法,无论是从缓存中获的 bean 还是根据不同的 scope 策略加载 bean 。总之,我们得到 bean 的实例后要做的第一步就是调用这个方法来检测一下正确性,其实就是用于检测当前 bean 是否是 FactroyBean 类型的 bean,如果是,那么需要调用该 bean 对应的 FactoryBean 实例中的 getObject() 作为返回值。
  再说详细一点:因为无论是从缓存中获取到的 bean 还是通过不同的 scope 策略加载的 bean 都只是最原始的 bean ,也即是说,缓存中记录的只是最原始的 bean 状态,并不一定是我们最终想要的 bean 。举个例子,当我们需要对 FactoryBean 即工厂 bean 进行处理,那么这里得到的其实是工厂 bean 的初始状态,但是我们真正需要的是工厂 bean 中定义的 factory-method 方法中返回的 bean ;另外也有可能我们需要返回的就是 FactoryBean 本身,而 #getObjectForBeanInstance 方法就是来完成这些处理的,代码如下:
/**
 * Get the object for the given bean instance, either the bean
 * instance itself or its created object in case of a FactoryBean.
 * <p>获取给定Bean实例的对象,如果是 FactoryBean ,则获取Bean实例本身或其创建的对象。
 * @param beanInstance the shared bean instance
 * @param name name that may include factory dereference prefix
 * @param beanName the canonical bean name
 * @param mbd the merged bean definition
 * @return the object to expose for the bean
 */
protected Object getObjectForBeanInstance(
        Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

    // Don't let calling code try to dereference the factory if the bean isn't a factory.
    // 1、如果指定的 name 是工厂类相关,即 & 前缀
    if (BeanFactoryUtils.isFactoryDereference(name)) {
        // 如果是 NullBean 类型则直接返回
        if (beanInstance instanceof NullBean) {
            return beanInstance;
        }
        // beanInstance 不是 FactoryBean 类型则验证不通过,抛出异常
        if (!(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
        }
        // 设置 isFactoryBean 标识为 true
        if (mbd != null) {
            mbd.isFactoryBean = true;
        }
        // 返回工厂 bean 本身
        return beanInstance;
    }

    // Now we have the bean instance, which may be a normal bean or a FactoryBean.
    // If it's a FactoryBean, we use it to create a bean instance, unless the
    // caller actually wants a reference to the factory.
    // 到这里我们已经有了一个 bean 实例,该实例可能是普通的 bean 或者是 FactoryBean,
    // 如果是 FactoryBean ,我们需要使用它来创建 bean 实例 ,除非是需要 FactoryBean 本身
    // 2、非 FactoryBean 的普通 bean ,直接返回
    if (!(beanInstance instanceof FactoryBean)) {
        return beanInstance;
    }

    Object object = null;
    if (mbd != null) {
        mbd.isFactoryBean = true;
    }
    else {
        // 3、如果 RootBeanDefinition 为 null,则尝试从 factoryBeanObjectCache 缓存中加载 bean
        object = getCachedObjectForFactoryBean(beanName);
    }
    // 若 object 依然为空,而到这里可以确认 beanInstance 一定是 FactoryBean 类型,则使用 FactoryBean 来创建 bean
    if (object == null) {
        // Return bean instance from factory.
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        // 检测 beanDefinitionMap 中也就是在所有已经加载的类中检测是否定义 beanName
        // Caches object obtained from FactoryBean if it is a singleton.
        if (mbd == null && containsBeanDefinition(beanName)) {
            // 将存储 XML 配置的 GenericBeanDefinition 转换成 RootBeanDefinition ,
            // 如果指定的 beanName 是子bean的话同时会合并父类的相关属性
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        // 是否是用户定义的而不是应用程序本身定义的
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        // 使用 FactoryBean 获得 Bean 实例对象
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}

  这个方法主要做了如下处理:

  • 1、校验 beanInstance 的正确性:如果指定的 name 是工厂类相关的( & 前缀)且 beanInstance 是 NullBean 类型则直接返回;如果 beanInstance 不是 FactoryBean 类型则抛出 BeanIsNotAFactoryException 异常;是 FactoryBean 则直接返回了。这个是需要返回 FactoryBean 本身的场景,后面则是需要返回 bean 实例。
  • 2、如果 beanInstance 不是 FactoryBean 类型,则直接返回该实例。
  • 3、如果 BeanDefinition 为空(前面调用传的就是空),则从 factoryBeanObjectCache 缓存中获取 bean 实例对象,如果还是为空,我们知道此时 beanInstance 肯定已经是 FactoryBean 类型,需要处理的就是通过 FactoryBean 来获得对应的 bean 实例,这里是通过委托 FactoryBeanRegistrySupport#getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) 方法来处理,可以猜想到的是,里面会调用 #getObject() 方法,获得最终自定义的 bean 实例。
 
  总之,这里区分了2种场景来处理:
  • 第1种是非 FactoryBean 类型,直接返回 bean 实例对象 beanInstance
  • 第2种就是 FactoryBean 类型,当然,如果确实是需要返回工厂类本身,这里直接就返回了 beanInstance ;如果不是,则是通过 FactoryBean 来获取实际的 bean 实例对象,也就是 #getObjectFromFactoryBean(...) 方法所作的事情。
  接下来我们把目光转移到核心方法 #getObjectFromFactoryBean 上。
 

2.1、getObjectFromFactoryBean

  代码如下:
/**
 * Obtain an object to expose from the given FactoryBean.
 * <p>从给定的 FactoryBean 中获取对象实例
 * @param factory the FactoryBean instance
 * @param beanName the name of the bean
 * @param shouldPostProcess whether the bean is subject to post-processing
 * @return the object obtained from the FactoryBean
 * @throws BeanCreationException if FactoryBean object creation failed
 * @see org.springframework.beans.factory.FactoryBean#getObject()
 */
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
    // 1、如果是单例模式且缓存中存在
    if (factory.isSingleton() && containsSingleton(beanName)) {
        // 1.1、对单例缓存加锁
        synchronized (getSingletonMutex()) {
            // 1.2、从缓存中获取指定的 bean 实例
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) {
                // 1.3、缓存中没有,则通过 FactoryBean 获取 bean 实例
                object = doGetObjectFromFactoryBean(factory, beanName);
                // 从缓存中获取,如果缓存中已经存在,则使用缓存中的实例
                // Only post-process and store if not put there already during getObject() call above
                // (e.g. because of circular reference processing triggered by custom getBean calls)
                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                if (alreadyThere != null) {
                    object = alreadyThere;
                }
                else {
                    // 1.4、需要后续处理
                    if (shouldPostProcess) {
                        // 如果 bean 实例还在创建中,则直接返回该对象实例
                        if (isSingletonCurrentlyInCreation(beanName)) {
                            // Temporarily return non-post-processed object, not storing it yet..
                            return object;
                        }
                        // 单例 bean 的创建前处理
                        beforeSingletonCreation(beanName);
                        try {
                            // 对从 FactoryBean 获取的实例进行后处理,主要是后处理器 BeanPostProcessor 处理
                            object = postProcessObjectFromFactoryBean(object, beanName);
                        }
                        catch (Throwable ex) {
                            throw new BeanCreationException(beanName,
                                    "Post-processing of FactoryBean's singleton object failed", ex);
                        }
                        finally {
                            // 单例 bean 创建完后置处理
                            afterSingletonCreation(beanName);
                        }
                    }
                    // 1.5、添加到 factoryBeanObjectCache 缓存中
                    if (containsSingleton(beanName)) {
                        this.factoryBeanObjectCache.put(beanName, object);
                    }
                }
            }
            return object;
        }
    }
    else {
        // 2、不是单例模式,则从 FactoryBean 中获取
        Object object = doGetObjectFromFactoryBean(factory, beanName);
        // 2.1、需要后续处理
        if (shouldPostProcess) {
            try {
                // 对从 FactoryBean 获取的实例进行后处理,主要是后处理器 BeanPostProcessor 处理
                object = postProcessObjectFromFactoryBean(object, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
            }
        }
        return object;
    }
}
  #getObjectFromFactoryBean 方法的主要处理流程如下:
  • 1、如果 FactoryBean 是单例模式且【一级缓存singletonObjects 中存在相关的 beanName ,则进行后续处理,否则按照非单例模式处理(第2步)
    • 1.1、首先,就是获取单例缓存 singletonObjects 的锁。可以发现,前面很多解析中也提到了 singletonObjects 的对象锁,这里是为了保证单例实例在单例模式中的唯一性,代码如下:
/// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

/**
 * Cache of singleton objects: bean name to bean instance.
 * <p>单例 bean 实例对象的缓存映射: beanName --> bean 实例。
 * <p>保存实例化、初始化都完成的单例 bean 对象,称为【一级缓存】
 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

@Override
public final Object getSingletonMutex() {
    return this.singletonObjects;
}
    •  1.2、其次,从缓存 factoryBeanObjectCache 中获取 bean 实例。如果存在,说明之前已经处理过,直接返回。
    • 1.3、如果不存在,则调用 #doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) 方法,从 FactoryBean 获取实例对象,内部其实就是调用了我们一直提到的 FactoryBean#getObject() 方法,代码如下,中间可以看到,确实是调用了 #getObject() 来获取实例对象:
/// org.springframework.beans.factory.support.FactoryBeanRegistrySupport

/**
 * Obtain an object to expose from the given FactoryBean.
 * <p>从给定的 FactoryBean 中获取对象实例
 * @param factory the FactoryBean instance
 * @param beanName the name of the bean
 * @return the object obtained from the FactoryBean
 * @throws BeanCreationException if FactoryBean object creation failed
 * @see org.springframework.beans.factory.FactoryBean#getObject()
 */
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
        throws BeanCreationException {

    Object object;
    try {
        // 权限验证
        if (System.getSecurityManager() != null) {
            AccessControlContext acc = getAccessControlContext();
            try {
                object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            // 直接调用 getObject 方法获取 bean 实例
            object = factory.getObject();
        }
    }
    catch (FactoryBeanNotInitializedException ex) {
        throw new BeanCurrentlyInCreationException(beanName, ex.toString());
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
    }

    // Do not accept a null value for a FactoryBean that's not fully
    // initialized yet: Many FactoryBeans just return null then.
    if (object == null) {
        // 如果当前 bean 正在创建中,则抛出异常
        if (isSingletonCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(
                    beanName, "FactoryBean which is currently in creation returned null from getObject");
        }
        // getObject 返回 null 则是统一使用 NullBean
        object = new NullBean();
    }
    return object;
}
    • 1.4、如果需要对新创建的 bean 实例进行后续处理,则
      • 如果该 bean 实例对象还在创建中,即 DefaultSingletonBeanRegistry#isSingletonCurrentlyInCreation(String beanName) 方法返回 true ,则直接返回该对象,无需进一步处理。
      • 调用 #beforeSingletonCreation(String beanName) 方法,进行创建之前的处理,默认实现是将该 bean 注册为正在创建中
      • 调用 #postProcessObjectFromFactoryBean(Object object, String beanName) 对从 FactoryBean 获取的实例进行后处理,主要扩展是后处理器 BeanPostProcessor 处理
      • 调用 #afterSingletonCreation(String beanName) 方法,进行 bean 对象实例创建完后处理,默认实现是将该 bean 标记为不在创建中,也即是从正在创建中移除
    • 1.5、将获得的 bean 对象添加到 1.2 中提到 factoryBeanObjectCache 中,以便下次获取该单例。
  • 2、此时已经知道是非单例模式,则直接调用 #doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) 方法,从 FactoryBean 获取实例对象,当然,这里如果需要后续处理的话,只需要调用 #postProcessObjectFromFactoryBean(Object object, String beanName) 对从 FactoryBean 获取的实例进行后处理,因为非单例模式并不需要标记状态,而是直接使用。
  至此我们已经基本了解了【bean的实例化】涉及到的核心方法 #getObjectFromFactoryBean 的处理流程。当然,这当中还涉及到了一些很眼熟而且需要我们关注的几个方法:
  • #isSingletonCurrentlyInCreation(String beanName)
  • #beforeSingletonCreation(String beanName)
  • #postProcessObjectFromFactoryBean(Object object, String beanName)
  • #afterSingletonCreation(String beanName)
 

2.2、isSingletonCurrentlyInCreation

  #isSingletonCurrentlyInCreation 方法主要用于检测 bean 当前是否在创建中,它记录着 bean 的加载状态,配合 #beforeSingletonCreation(String beanName)#afterSingletonCreation(String beanName) 这两方法,对循环依赖的判断有很大的作用。
  • #beforeSingletonCreation(String beanName):创建 bean 前调用,将该 beanName 标记为正在创建中;
  • #afterSingletonCreation(String beanName):创建 bean 后调用,将该 beanName 移除正在创建中的标记。
这一前一后的标记和移除标记,有利于在循环依赖中进行检测,使得可以提前引用正在创建中的 bean 。代码如下:
/// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

/**
 * Names of beans that are currently in creation.
 * <p>当前正在创建中的 beans 的 beanName 集合
 */
private final Set<String> singletonsCurrentlyInCreation =
        Collections.newSetFromMap(new ConcurrentHashMap<>(16));

/**
 * Return whether the specified singleton bean is currently in creation
 * (within the entire factory).
 * <p>返回指定的单例bean当前是否正在创建(在整个 beanFactory 内)。
 * @param beanName the name of the bean
 */
public boolean isSingletonCurrentlyInCreation(String beanName) {
    return this.singletonsCurrentlyInCreation.contains(beanName);
}
 

2.3、beforeSingletonCreation

  在单例创建前添加标志到 singletonsCurrentlyInCreation 中,表示正处于创建中状态,代码如下:
/// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

/**
 * Callback before singleton creation.
 * <p>The default implementation register the singleton as currently in creation.
 * <p>单例创建前回调,默认实现是将单例注册为正在创建中
 * @param beanName the name of the singleton about to be created
 * @see #isSingletonCurrentlyInCreation
 */
protected void beforeSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName);
    }
}

 

2.4、afterSingletonCreation

  在单例创建后从 singletonsCurrentlyInCreation 中移除标志,表示不再处于创建中状态,代码如下:

/// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

/**
 * Callback after singleton creation.
 * <p>The default implementation marks the singleton as not in creation anymore.
 * <p>单例创建后回调,默认实现是标记单例不在创建中,即从正在创建中移除
 * @param beanName the name of the singleton that has been created
 * @see #isSingletonCurrentlyInCreation
 */
protected void afterSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
}

 

2.5、postProcessObjectFromFactoryBean

  FactoryBeanRegistrySupport#postProcessObjectFromFactoryBean(Object object, String beanName) 方法主要是扩展进行后置处理,org.springframework.beans.factory.support.FactoryBeanRegistrySupport 中默认是空实现不进行处理,直接返回实例对象。代码如下:

/**
 * Post-process the given object that has been obtained from the FactoryBean.
 * The resulting object will get exposed for bean references.
 * <p>The default implementation simply returns the given object as-is.
 * Subclasses may override this, for example, to apply post-processors.
 * @param object the object obtained from the FactoryBean.
 * @param beanName the name of the bean
 * @return the object to expose
 * @throws org.springframework.beans.BeansException if any post-processing failed
 */
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
    return object;
}

  注释里面提到,子类可以重写此方法,用于扩展进行进行后置处理。我们看下 Spring 中已经提供的实现: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

 

2.6、AbstractAutowireCapableBeanFactory

  AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean 方法代码如下:
/// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

/**
 * Applies the {@code postProcessAfterInitialization} callback of all
 * registered BeanPostProcessors, giving them a chance to post-process the
 * object obtained from FactoryBeans (for example, to auto-proxy them).
 * <p>应用所有注册的 BeanPostProcessors 的 postProcessAfterInitialization 回调,
 * 使它们有机会对从 FactoryBeans 获取的对象进行后处理(例如,自动代理它们)。
 * @see #applyBeanPostProcessorsAfterInitialization
 */
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
    return applyBeanPostProcessorsAfterInitialization(object, beanName);
}

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

  可以看到, AbstractAutowireCapableBeanFactory 中的实现主要用于后处理器 BeanPostProcessor 对创建完的 bean 实例进行处理。关于后处理器的使用,本文暂且不表,后续文章将会进行详细的分析和介绍。这里,我们只需要了解在 Spring 获取 bean 的规则中有这样一条:尽可能保证所有 bean 初始化后都会调用注册的 BeanPostProcessor#postProcessAfterInitialization 方法进行处理,在实际开发过程中大可以针对此特性设计自己的业务逻辑。

 

3、参考

posted @ 2021-06-24 22:34  心明谭  阅读(285)  评论(0编辑  收藏  举报