Spring5源码7-Bean创建及初始化(上)

 2023-01-26
原文作者:hsfxuebao 原文地址:https://juejin.cn/post/7134511685217779719

欢迎大家关注 github.com/hsfxuebao ,希望对大家有所帮助,要是觉得可以的话麻烦给点一下Star哈

本文主要分析bean的创建过程。

1. refresh()

    // 容器刷新的十二大步骤
    @Override
    public void refresh() throws BeansException, IllegalStateException {
       synchronized (this.startupShutdownMonitor) {
             ...
    
             // Instantiate all remaining (non-lazy-init) singletons.
             // 11. 【大核心】bean创建:完成BeanFactory 初始化(工厂里面所有的组件都好了)
             /*
              * 这个方法一定要理解要具体看
              * 1、bean实例化过程
              * 2、ioc
              * 3、注解支持
              * 4、BeanPostProcessor的执行
              * 5、Aop的入口
              */
             finishBeanFactoryInitialization(beanFactory);
    
             ...
          }
          ...
       }
    }
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
       ...
       // Instantiate all remaining (non-lazy-init) singletons.
       // 初始化所有 非懒加载的单实例的bean
       beanFactory.preInstantiateSingletons();
    }
    public void preInstantiateSingletons() throws BeansException {
       ...
       List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
       // Trigger initialization of all non-lazy singleton beans...
       // 创建出所有的单实例bean
       for (String beanName : beanNames) {
          RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
          // 单实例 & 非抽象&不是懒加载
          if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
             // 如果是FactoryBean
             if (isFactoryBean(beanName)) {
                //
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                   FactoryBean<?> factory = (FactoryBean<?>) bean;
                   boolean isEagerInit;
                   if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                      isEagerInit = AccessController.doPrivileged(
                            (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                            getAccessControlContext());
                   }
                   else {
                      isEagerInit = (factory instanceof SmartFactoryBean &&
                            ((SmartFactoryBean<?>) factory).isEagerInit());
                   }
                   if (isEagerInit) {
                      getBean(beanName);
                   }
                }
             }
             // 不是FactoryBean则执行这个逻辑,普通的单实例非懒加载bean的创建
             else {
                // todo
                getBean(beanName);
             }
          }
       }

我们知道了 Spring 在容器刷新的后期 通过调用AbstractApplicationContext#finishBeanFactoryInitialization 方法来实例化了所有的非惰性bean。在这里面就通过 beanFactory.preInstantiateSingletons(); 调用了一个非常关键的方法 AbstractBeanFactory#getBean(java.lang.String),而其实际上调用的是 AbstractBeanFactory#doGetBean 方法。

    @Override
    public Object getBean(String name) throws BeansException {
       return doGetBean(name, null, null, false);
    }

如果说,Spring中,Bean 的发现是在 ConfigurationClassPostProcessor 中进行的。那么Bean的创建就是在 doGetBean方法中进行的。 doGetBean 完成了单例Bean的完整创建过程,包括bean的创建,BeanPostProcessor 的方法调用、init-method等方法的调用、Aware 等接口的实现。下面,我们开始来分析这个 doGetBean。

关于Bean 的加载过程,AbstractApplicationContext#finishBeanFactoryInitialization 经过几次跳转,最终会跳转到 AbstractBeanFactory#doGetBean 方法。每个bean的创建都会经历此方法,所以本文的主要内容是分析 AbstractBeanFactory#doGetBean

2. DefaultListableBeanFactory

需要强调的是,本文中调用 doGetBean 方法的是 AbstractBeanFactory 的子类DefaultListableBeanFactory。如下图:

202301012010277871.png

DefaultListableBeanFactory 结构图如下:

202301012010283802.png

DefaultListableBeanFactory 是 Spring默认的BeanFactory类型。

注意这里说的 BeanFactory 并不是指 ApplicationContext,而是 ApplicationContext 内部的一个BeanFactory

2.1 DefaultSingletonBeanRegistry

在这里我们只需要知道DefaultListableBeanFactory 继承了 DefaultSingletonBeanRegistry类,拥有了 DefaultSingletonBeanRegistry 一系列的 集合类型来保存Bean相关信息。

大体如下,其中我们主要只需要关注前四个即可:

        /** Cache of singleton objects: bean name to bean instance. */
        //	用于保存BeanName和创建bean实例之间的关系,即缓存bean。 beanname -> instance 
        private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    
        /** Cache of singleton factories: bean name to ObjectFactory. */
        // 用于保存BeanName和常见bean的工厂之间的关系。beanname-> ObjectFactory
        private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    
        /** Cache of early singleton objects: bean name to bean instance. */
        // 也是保存BeanName和创建bean实例之间的关系,与singletonObjects 不同的是,如果一个单例bean被保存在此,则当bean还在创建过程中(比如 A类中有B类属性,当创建A类时发现需要先创建B类,这时候Spring又跑去创建B类,A类就会添加到该集合中,表示正在创建),就可以通过getBean方法获取到了,其目的是用来检测循环引用。
        private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
    
        /** Set of registered singletons, containing the bean names in registration order. */
        // 用来保存当前所有已经注册的bean
        private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
    
        /** Names of beans that are currently in creation. */
        // 用来保存当前正在创建的Bean。也是为了解决循环依赖的问题
        private final Set<String> singletonsCurrentlyInCreation =
                        Collections.newSetFromMap(new ConcurrentHashMap<>(16));
    
        /** Names of beans currently excluded from in creation checks. */
        // 用来保存当前从创建检查中排除的bean名称
        private final Set<String> inCreationCheckExclusions =
                        Collections.newSetFromMap(new ConcurrentHashMap<>(16));
    
        /** List of suppressed Exceptions, available for associating related causes. */
        // 初始化过程中的异常列表
        @Nullable
        private Set<Exception> suppressedExceptions;
    
        /** Flag that indicates whether we're currently within destroySingletons. */
        // 标志是否在销毁BeanFactory过程中
        private boolean singletonsCurrentlyInDestruction = false;
    
        /** Disposable bean instances: bean name to disposable instance. */
        // 一次性bean实例:beanName -> 一次性实例。暂未明白
        private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
    
        /** Map between containing bean names: bean name to Set of bean names that the bean contains. */
        // 包含的Bean名称之间的映射:BeanName  -> Bean包含的BeanName集合
        private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
    
        /** Map between dependent bean names: bean name to Set of dependent bean names. */
        // bean dependent(依赖的集合) : beanName -> 依赖该beanName 的 bean,即 key代表的bean 被value 所依赖
        private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
    
        /** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
        // bean 被哪些bean依赖 :  beanName -> beanName 所依赖的 bean。即 key 依赖于value这些bean
        private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

2.1.1 关键缓存

下面挑出来几个关键缓存集合来描述:

  • singletonObjects :ConcurrentHashMap。最简单最重要的缓存Map。保存关系是 beanName :bean实例关系。单例的bean在创建完成后都会保存在 singletonObjects 中,后续使用直接从singletonObjects 中获取。
  • singletonFactories :HashMap。这是为了解决循环依赖问题,用于提前暴露对象,保存形式是 beanName : ObjectFactory<?>
  • earlySingletonObjects :HashMap。这也是为了解决循环依赖问题。和 singletonFactories 互斥。因为 singletonFactories 保存的是 ObjectFactory。而earlySingletonObjects 个人认为是 singletonFactories 更进一步的缓存,保存的是 ObjectFactory#getObject的结果。
  • registeredSingletons :LinkedHashSet,用于保存注册过的beanName。
  • singletonsCurrentlyInCreation : 保存当前正在创建的bean。当一个bean开始创建时将保存其beanName,创建完成后将其移除
  • dependentBeanMap :保存bean的依赖关系,比如A对象依赖于 B对象,会出现 B :A。即保存的是key 被value依赖
  • dependenciesForBeanMap :保存bean的依赖关系,不过和dependentBeanMap 反了过来。A对象依赖于 B对象,会出现 A :B。保存的是key 依赖于 value

我们拿一个简单的场景解释一下 singletonFactoriesearlySingletonObjects 的关系 。 下面的代码是 DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean) 。我们可以看到其判断逻辑,

  • 锁定 singletonObjects,毕竟要操作 singletonObjects
  • singletonFactories 中获取 ObjectFactory 缓存
  • 如果存在 ObjectFactory 缓存,则更进一步提取ObjectFactory#getObjectsingletonObject对象。将singletonObject 保存到 earlySingletonObjects 缓存中,同时从 singletonFactories中移除。
    // DCL
    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
       // Quick check for existing instance without full singleton lock
       // 检查单例缓存池 中有没有
       Object singletonObject = this.singletonObjects.get(beanName);  // 以及缓存
       // 如果当前bean正在创建中,而且缓存中没有则继续
       if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
          singletonObject = this.earlySingletonObjects.get(beanName); // 二级缓存
          if (singletonObject == null && allowEarlyReference) {
             synchronized (this.singletonObjects) {
                // Consistent creation of early reference within full singleton lock
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                   singletonObject = this.earlySingletonObjects.get(beanName);
                   if (singletonObject == null) {
                      ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);  // 三级缓存
                      if (singletonFactory != null) {
                         singletonObject = singletonFactory.getObject();
                         this.earlySingletonObjects.put(beanName, singletonObject);
                         this.singletonFactories.remove(beanName);
                      }
                   }
                }
             }
          }
       }
       return singletonObject;
    }

2.1.2 图解

补上一张图,来看一看 A,B循环依赖 singletonFactoriesearlySingletonObjects 的变化

202301012010289203.png

在创建过程中会被添加到 singletonFactories 中,但当bean被循环依赖时会被添加到 earlySingletonObjects 中。也即是说 earlySingletonObjects 中的bean都是被循环依赖的。

2.2 BeanDefinition

这里简单介绍一下,顾名思义,BeanDefinition是bean的信息,一个BeanDefinition 描述和定义了创建一个bean需要的所有信息,属性,构造函数参数以及访问它们的方法。还有其他一些信息,比如这些定义来源自哪个类等等。

对于XML 配置方式的Spring方式来说, BeanDefinition 是配置文件 < bean > 元素标签在容器中的内容表示形式。<bean>元素标签拥有class、scope、lazy-init等配置属性,BeanDefinition 则提供了相应的beanClass、scope、lazyinit属性,BeanDefinition 和 <bean> 中的属性是一一对应的。其中RootBeanDefinition 是最常用的实现类,一般对应< bean > 元素标签。

类似下图的定义:

202301012010294734.png 需要注意的是 BeanDefinition 是一个接口,在Spring 中存在多种实现,具体请参考:blog.csdn.net/andy_zhang2… www.cnblogs.com/loongk/p/12…

3. doGetBean:bean的加载

下面我们开始进入正题,进行 AbstractBeanFactory#doGetBean的内容分析。这个方法是一切的核心(Bean的创建过程也是在这个方法中完成)。首先我们先来整体过一遍方法代码。后面将会对一些关键点进行详细解释。

    protected <T> T doGetBean(
          String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
          throws BeansException {
    
       // 1. 提取出对应的beanName。会去除一些特殊的修饰符比如 "&"
       String beanName = transformedBeanName(name);
       Object beanInstance;
    
       // Eagerly check singleton cache for manually registered singletons.
       // 2. 尝试从缓存获取或者singletonFacotries中的ObjectFactory中获取。后续细讲
       Object sharedInstance = getSingleton(beanName);
       if (sharedInstance != null && args == null) {
          ...
          // 3. 返回对应的实例,有时候存在诸如FactoryBean的情况并不直接返回实例本身,
          // 而是返回指定方法返回的实例。这一步主要还是针对FactoryBean的处理。
          beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
       } // 默认第一次获取组件都会走到else中
       else {
          // Fail if we're already creating this bean instance:
          // We're assumably within a circular reference.
          // 4. 只有单例情况才会尝试解决循环依赖,原型模式直接抛出异常。因为原型模式无法解决循环依赖问题。
          if (isPrototypeCurrentlyInCreation(beanName)) {
             throw new BeanCurrentlyInCreationException(beanName);
          }
    
          // Check if bean definition exists in this factory.
          // 拿到整个BeanFactory的父工厂,从父工厂中尝试获取组件
          BeanFactory parentBeanFactory = getParentBeanFactory();
          // 5. 如果 beanDefinitionMap 中也就是在所有已经加载的类中不包含beanName,则尝试从parentBeanFactory中检测
          if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
             // Not found -> check parent.
             // 递归到BeanFactory中检测
             String nameToLookup = originalBeanName(name);
             if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                      nameToLookup, requiredType, args, typeCheckOnly);
             }
             else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
             }
             else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
             }
             else {
                return (T) parentBeanFactory.getBean(nameToLookup);
             }
          }
    
          // 如果不仅仅做类型检查则是创建bean,这里需要记录
          if (!typeCheckOnly) {
             // 这里是将 当前创建的beanName 保存到 alreadyCreated 集合中。
             // alreadyCreated 中的bean表示当前bean已经创建了,在进行循环依赖判断的时候会使用
             markBeanAsCreated(beanName);
          }
    
          StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
                .tag("beanName", name);
          try {
             if (requiredType != null) {
                beanCreation.tag("beanType", requiredType::toString);
             }
             // 6. 将当前 beanName 的 BeanDefinition 和父类BeanDefinition 属性进行一个整合
             RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
             checkMergedBeanDefinition(mbd, beanName, args);
    
             // Guarantee initialization of beans that the current bean depends on.
             // 7. 寻找bean的依赖: 获取初始化的依赖项
             String[] dependsOn = mbd.getDependsOn();
             // 如果需要依赖,则递归实例化依赖bean
             if (dependsOn != null) {
                // 看当前的bean 有没有依赖 其他Bean
                for (String dep : dependsOn) {
                   if (isDependent(beanName, dep)) {
                      throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                   }
                   registerDependentBean(dep, beanName);
                   try {
                      // 依赖了其他Bean,就先获取其他的Bean
                      getBean(dep);
                   }
                   ...
                }
             }
    
             // Create bean instance.  创建bean的实例
             // 8 针对不同的Scope 进行bean的创建
             // 实例化依赖的bean便可以实例化mdb本身了
             // singleton 模式的创建
             if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, () -> {
                   try {
                      // todo 创建bean实例
                      return createBean(beanName, mbd, args);
                   }
                  ...
                });
                // 检查当前bean是否是 FactoryBean
                beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
             }
    
             else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                // Prototype 模式的创建
                Object prototypeInstance = null;
                try {
                   beforePrototypeCreation(beanName);
                   prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                   afterPrototypeCreation(beanName);
                }
                beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
             }
    
             else {
                // 指定scope上实例化bean
                String scopeName = mbd.getScope();
                if (!StringUtils.hasLength(scopeName)) {
                   throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
                }
                Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                   throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                   Object scopedInstance = scope.get(beanName, () -> {
                      beforePrototypeCreation(beanName);
                      try {
                         return createBean(beanName, mbd, args);
                      }
                      finally {
                         afterPrototypeCreation(beanName);
                      }
                   });
                   beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                   throw new ScopeNotActiveException(beanName, scopeName, ex);
                }
             }
          }
          ...
          finally {
             beanCreation.end();
          }
       }
       // 9 类型转换, 转Object为bean信息
       return adaptBeanInstance(name, beanInstance, requiredType);
    }
    
    @SuppressWarnings("unchecked")
    <T> T adaptBeanInstance(String name, Object bean, @Nullable Class<?> requiredType) {
       // Check if required type matches the type of the actual bean instance.
       // 检查需要的类型是否符合bean 的实际类型
       if (requiredType != null && !requiredType.isInstance(bean)) {
          try {
             Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
             if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
             }
             return (T) convertedBean;
          }
          ...
       }
       return (T) bean;
    }

综上所属,doGetBean的 大体流程如下:

  1. 将传入的beanName 转化为合适的beanName。因为这里可能传入bean的别名,比如 FactoryBean 这里就是传入 “&beanName” , 这一步就会将其转化为 “beanName”
  2. 尝试从单例缓存中获取 bean,主要是尝试从 singletonObjectssingletonFactories 中获取实例。(这一步中还使用了 earlySingletonObjects 来判断循环依赖的问题)
  3. 如果第二步获取到了bean,则会针对处理 FactoryBean 这种特殊情况,以获取到正确的bean。(因为Factorybean 的话可能需要将其 getObject 方法的返回值作为bean注入到容器中)。
  4. 如果第二步没有获取到bean,则会检测其原型模式下的循环依赖情况,如果原型模式下有循环依赖,则直接抛出异常,因为原型模式下无法解决循环依赖。
  5. 如果第四步没有抛出异常,则会判断 当前BeanFactory 中是否包含该beanName 的定义信息,如果不包含,则会递归去 parentBeanFactory 中去寻找beanName的定义信息.
  6. 随后查询beanName 的 BeanDefinition 是否具有 父类的BeanDefinition, 如果有,则将 父类的一些属性和子类合并,形成一个新的BeanDefinition : mdb
  7. 获取mdb中的 depends-on 属性,优先将依赖的bean创建,随后再创建当前bean。
  8. 到这一步,则说明当前bean尚未创建,则会根据 singleton 或者 prototype 或其他逻辑,走不同的流程来创建bean
  9. 创建bean结束后,根据调用者需要的类型进行一个类型转换。比如调用者希望返回一个Integer,这里得到的结果却是String,则会进行一个类型的转换。

3.1 转换 beanName

    final String beanName = transformedBeanName(name);

这一步的目的是为了去除 beanName 的别名,获取bean的真正beanName。

这里的name传入的可能是 bean的别名,或者是FactoryBean类型的bean。所以需要一系列的解析,解析包括:

  • 去除 FactoryBean 的修饰符。也就是说如果 name = “&name” 或者 name = “&&name” 这种多&& 情况也会去除& 使得 name = “name”。
  • 取指定alias所表示的最终beanName。比如别名A指向B的bean,则会返回B。

代码如下:

    protected String transformedBeanName(String name) {
            return canonicalName(BeanFactoryUtils.transformedBeanName(name));
    }
    
    ....
    // 从别名中获取真正的beanName
    public String canonicalName(String name) {
            String canonicalName = name;
            // Handle aliasing...
            String resolvedName;
            do {
                    // 从aliasMap 中获取到真实的beanName
                    resolvedName = this.aliasMap.get(canonicalName);
                    if (resolvedName != null) {
                            canonicalName = resolvedName;
                    }
            }
            while (resolvedName != null);
            return canonicalName;
    }
    
    ....
    // BeanFactoryUtils 中
    public static String transformedBeanName(String name) {
            Assert.notNull(name, "'name' must not be null");
            // 如果不是以 & 开头直接返回
            if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
                    return name;
            }
            // 否则剪切到 开头的 & ,直至开头没有 &
            return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
                    do {
                            beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
                    }
                    while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
                    return beanName;
            });
    }

3.2 尝试从缓存中加载单例

        Object sharedInstance = getSingleton(beanName);

对于单例Bean来说, Spring只会在同一容器中创建一次,并将创建好的Bean 实例保存到 singletonObjects 中,下次再获取bean实例,直接从 singletonObjects 中获取。

这一步的目的是从尝试从缓存中获取实例。需要注意的是,Spring为了解决循环依赖问题, 在创建bean的原则是不等bean 创建完成就会将创建bean的ObjectFactory提早曝光加入到singletonFactories缓存中,一旦下一个bean创建时需要依赖上一个bean,则直接使用ObjectFactory。 关于循环依赖的更多问题,后面会介绍。

代码逻辑如下:

  1. 尝试从singletonObjects 中获取Bean 实例。获取不到说明该bean尚未创建成功
  2. isSingletonCurrentlyInCreation 返回 true,则说明当前bean 的创建过程存在循环依赖。下面的逻辑就是为了尝试解决循环依赖
  3. 尝试从 earlySingletonObjects 中获取,获取不到说明该bean并未在创建过程中。(为了解决循环依赖的问题)
  4. allowEarlyReference = true时,这个是针对循环引用的操作,是允许循环引用。
  5. 随后 从singletonFactories 中加载 ObjectFactory,并将结果保存到 earlySingletonObjects 中,同时将 singletonFactories 中关于bean的定义移除。(earlySingletonObjects 和 singletonFactories 互斥)

这里我们看到

  • singletonFactories 的映射关系是 beanName : ObjectFactory
  • earlySingletonObjects 的映射关系是 beanName : ObjectFactory#getObject

earlySingletonObjectssingletonFactories 更进一步的缓存,所以二者互斥,相同的对象,一个缓存中存在即可。

具体代码如下:

    // DCL
    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
       // Quick check for existing instance without full singleton lock
       // 检查单例缓存池 中有没有
       Object singletonObject = this.singletonObjects.get(beanName);  // 以及缓存
       // 如果当前bean正在创建中,而且缓存中没有则继续
       // 单例缓存中没有对象 && 当前单例bean正在创建中,这是为了解决循环依赖的问题
       if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
          // 如果此时bean正在加载(bean 在 earlySingletonObjects 中),则直接将singletonObject 返回。
          singletonObject = this.earlySingletonObjects.get(beanName); // 二级缓存
          // allowEarlyReference = true 才会允许循环依赖
          if (singletonObject == null && allowEarlyReference) {
             // 如果单例缓存中不存在该bean,则加锁进行接下来的处理
             synchronized (this.singletonObjects) {
                // Consistent creation of early reference within full singleton lock
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                   singletonObject = this.earlySingletonObjects.get(beanName);
                   if (singletonObject == null) {
                      // 当某些方法需要提前初始化的时候则会调用addSingletonFactory
                      // 将对应的ObjectFactory初始化策略存储在singletonFactories中
                      ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);  // 三级缓存
                      if (singletonFactory != null) {
                         // 调用预先设定的getObject方法
                         singletonObject = singletonFactory.getObject();
                         // 记录在缓存中,earlySingletonObjects 和 singletonFactories互斥
                         this.earlySingletonObjects.put(beanName, singletonObject);
                         this.singletonFactories.remove(beanName);
                      }
                   }
                }
             }
          }
       }
       return singletonObject;
    }

3.3 尝试从FactoryBean中获取对象

        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

当我们结束上一步之后,经过 sharedInstance != null && args == null 的判断后就会调用该方法。作为上一步获取到的结果 sharedInstance 。我们需要判断其是否是 FactoryBean 的 实现类,如果是,则需要将其getObject() 的结果注入。所以该方法的功能简单来说就是用来检测当前bean是否是FactoryBean类型的bean,如果是,则调用其getObject() 方法,并将其返回值作为bean。

代码逻辑大体如下:

  1. 首先是在 AbstractBeanFactory#getObjectForBeanInstance 中 判断程序是否想获取 FactoryBean实例(beanName 是否以 & 开头)。如果是判断当前beanInstance是否是 FactoryBean。如果是则返回,否则抛出异常
  2. 如果不是想获取FactoryBean,那么就是想获取bean实例了。那么判断此时的beanInstance是普通的bean还是FactoryBean类型,如果是普通的bean则直接返回。
  3. 此时beanInstance 必定是 FactoryBean类型并且程序想获取bean实例。那么首先尝试从缓存 factoryBeanObjectCache 中获取。获取失败,则调用FactoryBean#getObject 方法来获取bean实例。并且在允许调用后置方法的情况下(shouldPostProcess 为true),调用BeanPostProcessor#postProcessAfterInitialization 的方法。

下面我们来看详细代码

3.3.1 AbstractBeanFactory#getObjectForBeanInstance

调用了 AbstractBeanFactory#getObjectForBeanInstance:

    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 是否是想获取 工厂类 (name 以 & 开头) 
            if (BeanFactoryUtils.isFactoryDereference(name)) {
                    if (beanInstance instanceof NullBean) {
                            return beanInstance;
                    }
                    // 以&开头又不是FactoryBean实现类,则抛出异常
                    if (!(beanInstance instanceof FactoryBean)) {
                            throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
                    }
                    if (mbd != null) {
                            mbd.isFactoryBean = true;
                    }
                    return beanInstance;
            }
    
            // 2. 此时bean可能是 FactoryBean 或者 普通的bean。判断如果 beanInstance 不是 FactoryBean而是普通的bean, 就直接返回
            if (!(beanInstance instanceof FactoryBean)) {
                    return beanInstance;
            }
            // 3. 到这一步就可以确定,当前beanInstance 是FactoryBean,并且需要获取getObject() 的结果
            Object object = null;
            if (mbd != null) {
                    mbd.isFactoryBean = true;
            }
            else {
                    // 尝试从缓存中加载bean。这一步是从 factoryBeanObjectCache 集合中获取
                    // 在后面获取 bean 成功后,可能会将 其缓存到 factoryBeanObjectCache  中
                    object = getCachedObjectForFactoryBean(beanName);
            }
    
            if (object == null) {
                    // Return bean instance from factory.
                    FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
                    // containsBeanDefinition 检测  beanDefinitionMap中也就是所有已经加载的类中检测是否定义beanName
                    if (mbd == null && containsBeanDefinition(beanName)) {
                            // 合并父类bean 定义的属性
                            mbd = getMergedLocalBeanDefinition(beanName);
                    }
                    boolean synthetic = (mbd != null && mbd.isSynthetic());
                    // 4. 这一步中对FactoryBean进行了解析。
                    object = getObjectFromFactoryBean(factory, beanName, !synthetic);
            }
            return object;
    }

3.3.1.1 doGetObjectFromFactoryBean

getObjectFromFactoryBean 方法中 调用 doGetObjectFromFactoryBean 方法来获取 FactoryBean 中的 bean实例。下面我们来看一下getObjectFromFactoryBean 代码:

    protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
            // 判断是否是单例模式 && singletonObjects 尚未缓存该bean (containsSingleton调用的是 singletonObjects )
            if (factory.isSingleton() && containsSingleton(beanName)) {
                    synchronized (getSingletonMutex()) {
                            // 尝试从 factoryBeanObjectCache 缓存中获取
                            Object object = this.factoryBeanObjectCache.get(beanName);
                            if (object == null) {
                                    // 在这个方法中进行解析。调用 FactoryBean 的 getObject 方法
                                    object = doGetObjectFromFactoryBean(factory, beanName);
    
                                    // 因为是单例模式,所以要保证变量的全局唯一。所以这里如果缓存中已经创建好了bean则替换为已经创建好的bean
                                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                                    if (alreadyThere != null) {
                                            object = alreadyThere;
                                    }
                                    else {
                                            // 如果允许调用bean的后置处理器。因为这里是直接将bean创建返回了,如果要调用后置方法则只能在这里调用。
                                            if (shouldPostProcess) {
                                                    if (isSingletonCurrentlyInCreation(beanName)) {
                                                            // Temporarily return non-post-processed object, not storing it yet..
                                                            return object;
                                                    }
                                                    // 将beanName 添加到 singletonsCurrentlyInCreation 中缓存,表示当前bean正在创建中
                                                    beforeSingletonCreation(beanName);
                                                    try {
                                                            // 调用了ObjectFactory的后置处理器。
                                                            object = postProcessObjectFromFactoryBean(object, beanName);
                                                    }
                                                    catch (Throwable ex) {
                                                            throw new BeanCreationException(beanName,
                                                                            "Post-processing of FactoryBean's singleton object failed", ex);
                                                    }
                                                    finally {
                                                    // 将beanName 从 singletonsCurrentlyInCreation 中移除,表示当前bean已经创建结束
                                                            afterSingletonCreation(beanName);
                                                    }
                                            }
                                            // return this.singletonObjects.containsKey(beanName); 如果 singletonObjects缓存中存在当前beanName,则将其缓存到 factoryBeanObjectCache 中。
                                            if (containsSingleton(beanName)) {
                                                    // 这里保存的是 beanName : FactoryBean
                                                    this.factoryBeanObjectCache.put(beanName, object);
                                            }
                                    }
                            }
                            return object;
                    }
            }
            else {
                    // FactoryBean 非单例直接调用 getObject 方法
                    Object object = doGetObjectFromFactoryBean(factory, beanName);
                    // 如果允许调用后置方法,则调用postProcessObjectFromFactoryBean 方法
                    if (shouldPostProcess) {
                            try {
                                    object = postProcessObjectFromFactoryBean(object, beanName);
                            }
                            catch (Throwable ex) {
                                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                            }
                    }
                    return object;
            }
    }

3.4 原型模式的依赖检查 - isPrototypeCurrentlyInCreation

    if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
    }

后面会对循环依赖进行详细介绍,简而言之就是 单例模式下才会尝试去解决循环依赖的问题,而原型模式则无法解决。也就是 isPrototypeCurrentlyInCreation 返回true,则抛出异常。

需要注意的是还有一个 方法是 判断单例模式的依赖检查 : isSingletonCurrentlyInCreation

3.5 递归 parentBeanFactory

这一步的逻辑比较简单,如下:

  1. 首先通过 containsBeanDefinition(beanName)方法判断当前beanFactory中是否有bean的定义,如果有,皆大欢喜。直接进入下一步。
  2. 如果没有,且 parentBeanFactory 不为空,则会通过递归的方式,尝试从 parentBeanFactory 中加载bean定义。
    // 5. 如果 beanDefinitionMap 中也就是在所有已经加载的类中不包含beanName,则尝试从parentBeanFactory中检测
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            // 递归到BeanFactory中检测
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                                    nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else if (requiredType != null) {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            else {
                    return (T) parentBeanFactory.getBean(nameToLookup);
            }
    }

其中 DefaultListableBeanFactory#containsBeanDefinition 代码如下

    @Override
    public boolean containsBeanDefinition(String beanName) {
            Assert.notNull(beanName, "Bean name must not be null");
            return this.beanDefinitionMap.containsKey(beanName);
    }

3.6 合并 BeanDefinition

BeanDefinition 顾名思义,就是关于bean 的定义信息。通过xml的bean定义可以很清楚的看到一些属性定义。

所以这一步就是检查当前 BeanDefinition 是否有父BeanDefinition ,如果有将一些属性和当前bean合并,生成一个 RootBeanDefinition。

推荐阅读: blog.csdn.net/andy_zhang2…

    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    checkMergedBeanDefinition(mbd, beanName, args);

这一块的调用链路:getMergedLocalBeanDefinition -> getMergedBeanDefinition -> getMergedBeanDefinition。所以我们 这里直接来看 getMergedBeanDefinition 方法。

首先,mdb 即 MergedBeanDefinition 的缩写,即一个合并的beanDefinition。

    // 如果给定bean的定义是子bean定义,则通过与父级合并返回RootBeanDefinition。
    protected RootBeanDefinition getMergedBeanDefinition(
                    String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
                    throws BeanDefinitionStoreException {
    
            synchronized (this.mergedBeanDefinitions) {
                    RootBeanDefinition mbd = null;
                    RootBeanDefinition previous = null;
    
                    // Check with full lock now in order to enforce the same merged instance.
                    if (containingBd == null) {
                            mbd = this.mergedBeanDefinitions.get(beanName);
                    }
    
                    if (mbd == null || mbd.stale) {
                            previous = mbd;
                            // 判断如果parentName为空则没必要进行合并了,直接克隆返回即可
                            if (bd.getParentName() == null) {
                                    // Use copy of given root bean definition.
                                    if (bd instanceof RootBeanDefinition) {
                                            mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                                    }
                                    else {
                                            mbd = new RootBeanDefinition(bd);
                                    }
                            }
                            else {
                                    // Child bean definition: needs to be merged with parent.
                                    BeanDefinition pbd;
                                    try {
                                            // 转换beanName
                                            String parentBeanName = transformedBeanName(bd.getParentName());
                                            // 递归调用,解析更上层的parent BeanDefinition 
                                            if (!beanName.equals(parentBeanName)) {
                                                    pbd = getMergedBeanDefinition(parentBeanName);
                                            }
                                            else {
                                                    BeanFactory parent = getParentBeanFactory();
                                                    if (parent instanceof ConfigurableBeanFactory) {
                                                            pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                                                    }
                                                    else {
                                                            throw new NoSuchBeanDefinitionException(parentBeanName,
                                                                            "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                                                                            "': cannot be resolved without a ConfigurableBeanFactory parent");
                                                    }
                                            }
                                    }
                                    catch (NoSuchBeanDefinitionException ex) {
                                            throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                                                            "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
                                    }
                                    // Deep copy with overridden values.
                                    // 深拷贝
                                    mbd = new RootBeanDefinition(pbd);
                                    mbd.overrideFrom(bd);
                            }
    
                            // Set default singleton scope, if not configured before.
                            if (!StringUtils.hasLength(mbd.getScope())) {
                                    mbd.setScope(SCOPE_SINGLETON);
                            }
    
                            if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
                                    mbd.setScope(containingBd.getScope());
                            }
    
                            // Cache the merged bean definition for the time being
                            // (it might still get re-merged later on in order to pick up metadata changes)
                            if (containingBd == null && isCacheBeanMetadata()) {
                                    this.mergedBeanDefinitions.put(beanName, mbd);
                            }
                    }
                    if (previous != null) {
                            copyRelevantMergedBeanDefinitionCaches(previous, mbd);
                    }
                    return mbd;
            }
    }

3.7 寻找依赖

这一步也是针对 BeanDefinitiondependsOn 属性来说的(对应注解则是 @DependsOn。主要是 优先加载Bean 的 depends-on依赖。

注:在 BeanDefinition 加载过程中,通过扫描路径加载的时候,通过 ClassPathBeanDefinitionScanner#doScan方法时会调用AnnotationConfigUtils#processCommonDefinitionAnnotations 来进行BeanDefinition 封装,其中就包含了诸多注解的解析,如下:

    // 解读所有bean定义信息需要感知的注解
    static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
       AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
       if (lazy != null) {
          abd.setLazyInit(lazy.getBoolean("value"));
       }
       else if (abd.getMetadata() != metadata) {
          lazy = attributesFor(abd.getMetadata(), Lazy.class);
          if (lazy != null) {
             abd.setLazyInit(lazy.getBoolean("value"));
          }
       }
    
       if (metadata.isAnnotated(Primary.class.getName())) {
          abd.setPrimary(true);
       }
       AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
       if (dependsOn != null) {
          abd.setDependsOn(dependsOn.getStringArray("value"));
       }
    
       AnnotationAttributes role = attributesFor(metadata, Role.class);
       if (role != null) {
          abd.setRole(role.getNumber("value").intValue());
       }
       AnnotationAttributes description = attributesFor(metadata, Description.class);
       if (description != null) {
          abd.setDescription(description.getString("value"));
       }
    }

因为bean 的初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的bean,那么这个时候就有必要先加载依赖的bean,所以,在Spring的加载顺寻中,在初始化某一个bean的时候首先会初始化这个bean所对应的依赖。

    // 获取依赖项
    String[] dependsOn = mbd.getDependsOn();
    if (dependsOn != null) {
            for (String dep : dependsOn) {
                    // 判断是否有循环依赖的情况 : A依赖B,B依赖A
                    if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                            "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    // 注册依赖信息,将依赖信息保存到 dependentBeanMap、dependenciesForBeanMap中
                    registerDependentBean(dep, beanName);
                    try {
                            // 获取依赖的bean,这一步又回到了最初的getBean
                            getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                            "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
            }
    }

下面我们来看一看 isDependent(beanName, dep) 的处理逻辑

    private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
            // 是否已经检测过了,上层一直是null
            if (alreadySeen != null && alreadySeen.contains(beanName)) {
                    return false;
            }
            // 格式化beanName
            String canonicalName = canonicalName(beanName);
            // 获取 依赖于 beanName 的 bean集合
            Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
            if (dependentBeans == null) {
                    return false;
            }
            // 如果 依赖于 beanName中存在 dependentBeanName 则说明存在循环依赖。
            // 代码走到这里说明是beanName 创建过程中要依赖 dependentBeanName。但是dependentBeans.contains(dependentBeanName) = true 则说明dependentBeanName依赖于beanName
            // 造成了 A依赖B,B依赖A的情况
            if (dependentBeans.contains(dependentBeanName)) {
                    return true;
            }
            // 递归,确定没有A->B->C-A 这种长链路的循环依赖情况
            for (String transitiveDependency : dependentBeans) {
                    if (alreadySeen == null) {
                            alreadySeen = new HashSet<>();
                    }
                    alreadySeen.add(beanName);
                    if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
                            return true;
                    }
            }
            return false;
    }

注: @DependsOn:注解是在另外一个实例创建之后才创建当前实例,也就是,最终两个实例都会创建,只是顺序不一样 @ConditionalOnBean :注解是只有当另外一个实例存在时,才创建,否则不创建,也就是,最终有可能两个实例都创建了,有可能只创建了一个实例,也有可能一个实例都没创建

3.8 bean创建

上面这么多逻辑,都是准备工作。确定缓存中没有当前bean,并且当前bean的创建合法。准备开始创建。不过这里考虑到不同的 Scope,所以针对不同的Scope进行不同的初始化操作。创建bean 的过程也很复杂。

下面代码就是根据 Singleton、Prototype 或者其他Scope 走不同的流程创建bean。

    // Create bean instance.
    if (mbd.isSingleton()) {
            // 单例的创建
            sharedInstance = getSingleton(beanName, () -> {
                    try {
                            return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                    }
            });
            // 解决FactoryBean的问题
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
    
    else if (mbd.isPrototype()) {
            // It's a prototype -> create a new instance.
            // 原型模式的回调
            Object prototypeInstance = null;
            try {
                    // 保存当前线程正在创建的beanName 到 prototypesCurrentlyInCreation 中
                    beforePrototypeCreation(beanName);
                    // 直接创建bean
                    prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
                    // 移除当前线程正在创建的beanName 从 prototypesCurrentlyInCreation 中
                    afterPrototypeCreation(beanName);
            }
            // 解决FactoryBean的问题
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    }
    
    else {
            String scopeName = mbd.getScope();
            final Scope scope = this.scopes.get(scopeName);
            if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
            }
            try {
                    Object scopedInstance = scope.get(beanName, () -> {
                    // 保存当前线程正在创建的beanName 到 prototypesCurrentlyInCreation 中
                            beforePrototypeCreation(beanName);
                            try {
                                    // 创建bean
                                    return createBean(beanName, mbd, args);
                            }
                            finally {
                                    // 移除当前线程正在创建的beanName 从 prototypesCurrentlyInCreation 中
                                    afterPrototypeCreation(beanName);
                            }
                    });
                    //  解决FactoryBean的问题
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
            }
            catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName,
                                    "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                    "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                    ex);
            }
    }

关于 bean 创建的过程 getSingleton ,下面进行分析。

3.9 类型转换

到这里整个流程基本就结束了。通常对该方法的调用参数 requiredType 是null,。但某些情况可能会出现返回的bean是个String类型,但是requiredType 传入的却是Integer类型,这时候就会触发这一步的操作,将String类型转换为Integer类型。

    if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                    T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                    if (convertedBean == null) {
                            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                    }
                    return convertedBean;
            }
            catch (TypeMismatchException ex) {
                    if (logger.isTraceEnabled()) {
                            logger.trace("Failed to convert bean '" + name + "' to required type '" +
                                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                    }
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
    }

4. getSingleton:bean的获取

DefaultSingletonBeanRegistry#getSingleton(java.lang.String, ObjectFactory<?>)这一步创建了bean,我们来分析 getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法整个流程。

4.1 获取单例 - getSingleton

如下, 是整个 getSingleton方法的代码,做了一些基本注释

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
            Assert.notNull(beanName, "Bean name must not be null");
            // 因为创建过程中需要操作 singletonObjects。所以需要加锁
            synchronized (this.singletonObjects) {
                    // 1. 再次尝试获取bean,判断bean是否已经加载。如果加载直接返回。
                    Object singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                            // 2. 判断,如果当前beanFactory正在被销毁则直接抛出异常,不允许创建单例bean
                            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 (logger.isDebugEnabled()) {
                                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                            }
                            // 3. 做一些bean创建前的准备工作: 记录beanName 正在加载的状态(添加到 singletonsCurrentlyInCreation 缓存中),若bean已经正在加载,则抛出异常。为了解决循环引用的问题
                            beforeSingletonCreation(beanName);
                            boolean newSingleton = false;
                            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                            if (recordSuppressedExceptions) {
                                    this.suppressedExceptions = new LinkedHashSet<>();
                            }
                            try {
                                    // 4. 通过回调方式获取bean实例。
                                    singletonObject = singletonFactory.getObject();
                                    newSingleton = true;
                            }
                            catch (IllegalStateException ex) {
                                    // Has the singleton object implicitly appeared in the meantime ->
                                    // if yes, proceed with it since the exception indicates that state.
                                    singletonObject = this.singletonObjects.get(beanName);
                                    if (singletonObject == null) {
                                            throw ex;
                                    }
                            }
                            catch (BeanCreationException ex) {
                                    if (recordSuppressedExceptions) {
                                            for (Exception suppressedException : this.suppressedExceptions) {
                                                    ex.addRelatedCause(suppressedException);
                                            }
                                    }
                                    throw ex;
                            }
                            finally {
                                    if (recordSuppressedExceptions) {
                                            this.suppressedExceptions = null;
                                    }
                                    // 5. 加载单例后的处理方法调用 : 删除bean正在创建的记录(从 singletonsCurrentlyInCreation  中移除 beanName)
                                    afterSingletonCreation(beanName);
                            }
                            if (newSingleton) {
                                    // 6. 加入到缓存中,并删除加载bean过程中所记录的各种辅助状态
                                    addSingleton(beanName, singletonObject);
                            }
                    }
                    return singletonObject;
            }
    }
    
    ...
    // 主要还是对几个缓存map的操作
    protected void addSingleton(String beanName, Object singletonObject) {
            synchronized (this.singletonObjects) {
                    this.singletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                    this.earlySingletonObjects.remove(beanName);
                    this.registeredSingletons.add(beanName);
            }
    }
    ...
    // 不包含 && 添加失败 :则认为Bean正在创建中,抛出异常
    protected void beforeSingletonCreation(String beanName) {
            if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
                    throw new BeanCurrentlyInCreationException(beanName);
            }
    }
    ...
    // 不包含 && 移除失败 :认为Bean 已经创建结束,抛出异常。
    protected void afterSingletonCreation(String beanName) {
            if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
                    throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
            }
    }

上面的代码注释也比较清楚,基本流程如下:

  1. this.singletonObjects.get(beanName); :再次尝试从缓存中获取bean,若获取到,则直接返回。
  2. if (this.singletonsCurrentlyInDestruction) :未获取到检测bena是否正在销毁,若是则抛出异常
  3. beforeSingletonCreation方法中记录bean正在创建的状态将beanName添加到singletonsCurrentlyInCreation集合中)。在循环依赖时可根据此判断。
  4. singletonObject = singletonFactory.getObject(); :调用 ObjectFactory.getObject() 方法来实例化bean
  5. afterSingletonCreation 方法移除bean正在夹杂的状态
  6. addSingleton(beanName, singletonObject); : 对各种缓存状态做处理。

流程图如下所示 :下面的流程图关于 beforeSingletonCreation 和 afterSingletonCreation 的注释写的有些问题,正确的描述如下:

  • inCreationCheckExclusions 不包含 beanName && singletonsCurrentlyInCreation 添加失败 :则认为Bean正在创建中,抛出异常
  • inCreationCheckExclusions 不包含 beanName && singletonsCurrentlyInCreation 移除失败 :认为Bean 已经创建结束,抛出异常。

202301012010303255.png

可以非常直观的看出, getSingleton 方法中的关键逻辑非常简单,bean创建的具体逻辑在 singletonObject = singletonFactory.getObject();中,所以下面继续去分析singletonFactory.getObject()中做了什么。

4.2 创建bean - createBean概述

上面可以看到,主要步骤还是在回调的 getObject() 方法中。那么我们来看看在bean加载过程中的FactoryBean做了什么。代码如下:

202301012010311996.png

兜了一大圈关键代码还是在createBean 方法里。接下来,我们就来仔细分析一下 createBean 方法。

AbstractAutowireCapableBeanFactory#createBean 方法代码如下 ,附带部分注释:

    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                    throws BeanCreationException {
    
    
            RootBeanDefinition mbdToUse = mbd;
    
    
            // 1. 锁定class, 根据mdb和 beanName 解析出来 class
            Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
            if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
                    mbdToUse = new RootBeanDefinition(mbd);
                    mbdToUse.setBeanClass(resolvedClass);
            }
    
            // Prepare method overrides.
            try {
                    // 2. 验证及准备覆盖的方法
                    mbdToUse.prepareMethodOverrides();
            }
            catch (BeanDefinitionValidationException ex) {
                    throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                                    beanName, "Validation of method overrides failed", ex);
            }
    
            try {
                    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
                    // 3. 调用BeanProcessors的方法来替代真正的实例
                    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
                    // 如果后处理器真的实现了,则直接返回使用后处理器的bean
                    if (bean != null) {
                            return bean;
                    }
            }
            catch (Throwable ex) {
                    throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                                    "BeanPostProcessor before instantiation of bean failed", ex);
            }
    
            try {
                    // 4.  创建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);
            }
    }

可以看到,createBean 的整体流程大致如下:

  1. 根据设置的class属性或者根据className来解析Class。
  2. 对override 属性进行标记及验证。
  3. 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作。
  4. 创建bean。
  5. 返回bean

流程图如下:

202301012010324457.png

上面的逻辑看着似乎不复杂,实际上,真正的逻辑都被封装在了方法中,所以下面需要关注如下的几个方法:

4.2.1 resolveBeanClass

这里不再过多展示代码,这个方法的作用就是根据参数和返回值都能知道: 根据 BeanDefinition和 beanName 解析出 bean 的Class。

    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);

4.2.2 prepareMethodOverrides

见名知意: 准备方法重写,这里更多是做一个校验的功能。这个方法主要是针对 lookup-method 和 replaced-method 两个属性的,用来覆盖指定的方法。

    mbdToUse.prepareMethodOverrides();

详细代码如下:

    public void prepareMethodOverrides() throws BeanDefinitionValidationException {
       // Check that lookup methods exist and determine their overloaded status.
       // 判断是否有方法需要重写
       if (hasMethodOverrides()) {
          getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
       }
    }
    protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
       // 获取对应的类中的对应方法名的个数
       int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
       // 等于0抛出异常。上面已经验证有方法需要覆盖,这里为0肯定错误
       if (count == 0) {
          throw new BeanDefinitionValidationException(
                "Invalid method override: no method with name '" + mo.getMethodName() +
                "' on class [" + getBeanClassName() + "]");
       }
       else if (count == 1) {
          // Mark override as not overloaded, to avoid the overhead of arg type checking.
          // 标记 MethodOverride 暂未被覆盖,避免参数类型检查的开销。
          mo.setOverloaded(false);
       }
    }

解释一下上面的逻辑:

  1. 首先会判断是否有方法需要重写,这里的是根据 RootBeanDefinition 中的 methodOverrides 属性来进行判断,为空则表示没有。
  2. 若上述判断有方法需要覆盖,则会调用prepareMethodOverride(MethodOverride mo) 方法。而在 prepareMethodOverride(MethodOverride mo) 方法中会根据 需要覆盖的方法名称 来获取加载类中关于该方法的实现。如果获取不到 count == 0,则直接抛出异常,如果获取到只有一个 count == 1,则记录该方法并未被重载(因为Spring在方法匹配时,如果一个类中存在若干个重载方法,则在函数调用及增强的时候需要根据参数类型进行匹配,来最终确定调用的方法是哪一个,这里直接设置了该方法并未被重载,在后续方法匹配的时候就不需要进行参数匹配验证,直接调用即可)。
  3. 打个比方,比如指定覆盖A类中的 a方法,但是A类中可能存在多个a方法或者不存在a方法,若count == 0不 存在a方法,则谈何覆盖,直接抛出异常,若count ==1 则a方法的实现只有一个,标记该方法并未被重载后续可跳过参数验证的步骤。

4.2.3 resolveBeforeInstantiation

该方法主要是调用 InstantiationAwareBeanPostProcessor 来进行一些处理,这里实际上是给了用户一次代替Spring来创建bean的机会,代码实现上非常简单直接调用的后处理器方法。

    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    // 如果通过后置处理器创建出来bean,则直接返回创建的bean
    if (bean != null) {
            return bean;
    }

该方法调用了后处理器的方法:

  • InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation: 在bean初始化前调用
  • BeanPostProcessor#postProcessAfterInitialization : 在bean初始化后调用
  • 关于后置处理器部分具体介绍请看Spring5源码5-Bean生命周期后置处理器

详细代码如下:在调用 doCreate 方法创建bean的实例前调用了该方法对 BeanDefinition 中的属性做一些前置处理。

    @Nullable
    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
            Object bean = null;
            // 如果尚未被解析
            if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
                    // Make sure bean class is actually resolved at this point.
                    // 当前类并非合成类 && 存在 BeanPostProcessor (后处理器)
                    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                            // 1. 获取目标类
                            Class<?> targetType = determineTargetType(beanName, mbd);
                            if (targetType != null) {
                                    // 2. 实例前的后处理器应用
                                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                                    if (bean != null) {
                                            // 3. 实例后的后处理器应用
                                            bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                                    }
                            }
                    }
                    mbd.beforeInstantiationResolved = (bean != null);
            }
            return bean;
    }

其中 applyBeanPostProcessorsBeforeInstantiationapplyBeanPostProcessorsAfterInitialization 很明显就是调用bean的后置处理器,也就是对后置处理器中的 InstantiationAwareBeanPostProcessor 类型的后处理器进行 postProcessBeforeInstantiation 方法BeanPostProcessor 类型的 postProcessAfterInitialization 方法的调用。

4.2.3.1 determineTargetType(beanName, mbd);

关于 factoryMethodName 值的由来,即如果通过@Bean 注入,则保存期工厂类的方法名称,简单来说就是配置类中对应该bean的注入方法名称。

    @Nullable
    protected Class<?> determineTargetType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
            // 获取目标类。这里获取的目标类并不一定是真正生成的类,可能是其真正类的父类或者父接口
            Class<?> targetType = mbd.getTargetType();
            if (targetType == null) {
                    // 根据mdb 是否存在 factoryMethodName 来确定是直接解析class还是通过 工厂类的方法返回值来获取class
                    targetType = (mbd.getFactoryMethodName() != null ?
                                    getTypeForFactoryMethod(beanName, mbd, typesToMatch) :
                                    resolveBeanClass(mbd, beanName, typesToMatch));
                    if (ObjectUtils.isEmpty(typesToMatch) || getTempClassLoader() == null) {
                            mbd.resolvedTargetType = targetType;
                    }
            }
            return targetType;
    }

需要注意的是 这里获取的 targetType 类型并不一定是真正生成的bean类型,也可能是实际类型 的父类或者父接口 。因为对于通过 @Bean 注解修饰注入到Spring容器的时候,BeanDefinitionfactoryMethodName 属性值不为空,指向其工厂类的方法名。并且由于多态的特性,其工厂方法引入的类型并不一定是实际类型。这个类型的错误会在AbstractAutowireCapableBeanFactory#doCreateBean 中纠正过来.

比如 :下面的 demoService()方法实际生成的类型是 DemoServiceImpl。这里返回的类型是DemoService 。那么我们这里获取到的 targetType 就是 DemoService.class。其 BeanDefinition.factoryMethodName = demoService (即 DemoConfig 生成DemoService的方法的名称)

    public class DemoConfig {
        @Bean
        public DemoService demoService() {
            return new DemoServiceImpl();
        }
    }

4.2.3.2 postProcessBeforeInstantiation

在bean 实例化前调用,也就是将 AbstractBeanDefinition 转换为 BeanWrapper 前的处理。给子类一个修改BeanDefinition的机会,也就是说当程序经过这个方法后,bean可能已经不是我们所认为的bean了。或许是一个经过代理的代理bean。可能是通过cglib生成的,也可能是通过其他技术生成的。

    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
            // 获取所有 BeanPostProcessor 进行遍历
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;				
                            // 调用 postProcessBeforeInstantiation 方法
                            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                            if (result != null) {
                                    return result;
                            }
                    }
            }
            return null;
    }

4.2.3.3 postProcessAfterInitialization

这里是bean创建后的后置方法调用,逻辑基本类似。不同的是到达这一步时,Bean已经创建成功,并且注入属性也进行了赋值。

需要注意,如果bean交由Spring来创建,那么Spring会将需要的属性注入到bean中,如果是自己代理生成(比如 通过 postProcessBeforeInstantiation 方法生成),那么需要自己解决bean的属性注入问题。

    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;
    }

4.3 创建bean - doCreateBean

代码执行到这里,可以确定第三步中并没有返回一个非空的bean(BeanPostProcessor 并没有代理生成一个bean)。所以Spring开始自己着手创建bean。do开头的方法才是真正做事情的,所以这里才是真正创建bean的地方。

    Object beanInstance = doCreateBean(beanName, mbdToUse, args);

doCreateBean 代码如下,带有详细注释:

    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
          throws BeanCreationException {
    
       // Instantiate the bean.
       BeanWrapper instanceWrapper = null;
       // 是否单例
       if (mbd.isSingleton()) {
          // 单例情况下清除缓存。这里保存的是 FactoryBean 和 BeanWrapper 的映射关系。
          // factoryBeanInstanceCache 是在创建其他bean的时候缓存了一下 FactoryBean 。
          // 至于单例模式下移除而不是获取,因为单例只需要创建一次 ? 尚未理解。
          instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
       }
       // 如果没有缓存,则重新创建
       if (instanceWrapper == null) {
          // todo 创建Bean实例 ,默认使用无参构造器创建的对象,组件的实例就创建了
          // 1. 根据指定的bean使用对应的策略创建新的实例。如:工厂方法、构造函数自动注入,简单初始化
          instanceWrapper = createBeanInstance(beanName, mbd, args);
       }
       // 获取bean实例
       Object bean = instanceWrapper.getWrappedInstance();
       // 获取bean类型
       Class<?> beanType = instanceWrapper.getWrappedClass();
       // 将目标类型替换成实际生成的类型.纠正了上面说到类型错误(如果存在)
       if (beanType != NullBean.class) {
          mbd.resolvedTargetType = beanType;
       }
    
       // Allow post-processors to modify the merged bean definition.
       // MergedBeanDefinitionPostProcessor 后置处理器再来修改下BeanDefinition 信息
       // 2. 调用  MergedBeanDefinitionPostProcessor 后处理器
       synchronized (mbd.postProcessingLock) {
          if (!mbd.postProcessed) {
             try {
                // todo 执行MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()方法
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
             }
             catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                      "Post-processing of merged bean definition failed", ex);
             }
             mbd.postProcessed = true;
          }
       }
    
       // Eagerly cache singletons to be able to resolve circular references
       // even when triggered by lifecycle interfaces like BeanFactoryAware.
       // 提前暴露 单实例bean 专门来解决循坏引用的问题
       // 3. 判断是否需要提早曝光 : 单例 & 允许循环依赖 & 当前bean已经正在创建中
       // 由于当前bean已经在创建中,本次创建必然是循环引用造成的,所以这里判断是否可以需要提前曝光
       boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
             isSingletonCurrentlyInCreation(beanName));
       if (earlySingletonExposure) {
          if (logger.isTraceEnabled()) {
             logger.trace("Eagerly caching bean '" + beanName +
                   "' to allow for resolving potential circular references");
          }
          // 添加
          // 三级缓存中Bean也会被后置处理来增强
          // 4. 为避免后期循环依赖,在bean初始化完成前将创建实例的ObjectFactory 加入工程  -- 解决循环依赖
          addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
       }
    
       // Initialize the bean instance.
       Object exposedObject = bean;
       try {
          // todo 对象中的每个属性赋值
          //  5. 对bean进行属性填充,将各个属性值注入,其中如果存在依赖于其他bean的属性,则会递归初始依赖bean
          populateBean(beanName, mbd, instanceWrapper);
          // todo 初始化Bean
          // 调用初始化方法,比如 init-method
          exposedObject = initializeBean(beanName, exposedObject, mbd);
       }
       catch (Throwable ex) {
          if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
             throw (BeanCreationException) ex;
          }
          else {
             throw new BeanCreationException(
                   mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
          }
       }
       // 早期单实例暴露
       // 6. 进行循环依赖检查
       if (earlySingletonExposure) {
          // 检查早期缓存中是否存在这个组件
          // earlySingletonReference  只有在检测到有循环依赖的情况下才会不为空
          Object earlySingletonReference = getSingleton(beanName, false);
          if (earlySingletonReference != null) {
             // 如果 exposedObject没有在初始化方法中被改变,也就是没有被增强
             if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
             }
             else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                   // 检测依赖
                   if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                      actualDependentBeans.add(dependentBean);
                   }
                }
                // 因为bean创建后其所依赖的bean一定是已经创建了的。
                // actualDependentBeans不为空说明当前 bean创建后其依赖的bena却没有全部创建完,也就说说存在循环依赖。
                if (!actualDependentBeans.isEmpty()) {
                   throw new BeanCurrentlyInCreationException(beanName,
                         "Bean with name '" + beanName + "' has been injected into other beans [" +
                         StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                         "] in its raw version as part of a circular reference, but has eventually been " +
                         "wrapped. This means that said other beans do not use the final version of the " +
                         "bean. This is often the result of over-eager type matching - consider using " +
                         "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
             }
          }
       }
    
       // Register bean as disposable.
       try {
          // 7.根据Scopse 注册bean
          registerDisposableBeanIfNecessary(beanName, bean, mbd);
       }
       catch (BeanDefinitionValidationException ex) {
          throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
       }
    
       return exposedObject;
    }

可以看到大致逻辑如下:

  1. createBeanInstance(beanName, mbd, args) :实例化bean,将BeanDefinition转换为BeanWrapper
  2. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);: MergedBeanDefinitionPostProcessor 后处理器的应用。bean合并后的处理,比如 @Autowired、@Value注解正是通过 AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition 此方法实现的预解析。
  3. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); : 关于循环依赖的处理,添加 ObjectFactory到singletonFactories缓存中,同时这里给了用户一个机会通过调用 SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference 方法来由用户生成暴露的实例
  4. populateBean(beanName, mbd, instanceWrapper);:对创建的bean内部的一些属性进行填充注入
  5. initializeBean(beanName, exposedObject, mbd); : 初始化bean的一些属性,如Aware 接口的实现, init-method属性等
  6. 循环依赖检查。和第四步不同的是,这里了是判断是否无法解决循环依赖,否则抛出异常。
  7. registerDisposableBeanIfNecessary(beanName, bean, mbd); : 注册DisposableBean
  8. 完成创建并返回。

doCreatebean 方法的代码量非常大,这里由于篇幅问题,需要新开篇分析,所以本文中挑选几个简单的方法分析,复杂的方法新开篇分析。

4.3.1 createBeanInstance

见名知意 : 该方法完成了bean的实例创建。

    instanceWrapper = createBeanInstance(beanName, mbd, args);

大概逻辑可以概括为:

  • 如果存在工厂方法则使用工厂方法进行初始化
  • 若类有多个构造函数,则根据参数锁定构造函数并初始化
  • 如果即不存在工厂方法也不存在带参构造函数,则使用默认的构造函数进行bean的实例化。

这里详细见第5小节分析。

4.3.2 applyMergedBeanDefinitionPostProcessors

这种方法命名的也见得多了,见名知意: 该方法完成了 MergedBeanDefinitionPostProcessors 后处理器的功能。主要是 bean合并后的处理。在 AutowiredAnnotationBeanPostProcessor对postProcessMergedBeanDefinition方法的实现中,就对@Autowired、@Value 等注解进行了一系列的预处理,这里我们并不需要太过在意。

关于 AutowiredAnnotationBeanPostProcessor 的内容,后面单独开一篇来分析。

    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

详细代码如下,不再具体分析

    protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof MergedBeanDefinitionPostProcessor) {
                            MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                            bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
                    }
            }
    }

4.3.3 addSingletonFactory

这一部分的逻辑就是为了解决循环依赖的问题,将未创建完成的当前bean,通过ObjectFactory进行一个包装,提前暴露给其他bean。

我们实际的分析是一部分代码块如下:

    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
            if (logger.isTraceEnabled()) {
                    logger.trace("Eagerly caching bean '" + beanName +
                                    "' to allow for resolving potential circular references");
            }
            // 这里为了避免后期的循环依赖,在bean初始化前将创建实例的ObjectFactory加入工厂中。
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

首先我们需要分析出 earlySingletonExposure 为true的条件:

  • bean是单例
  • 允许循环依赖
  • 当前bean正在创建中 : singletonsCurrentlyInCreation 包含当前bean。在Spring 中 有专门的属性记录 bean的加载状态 – DefaultSingletonBeanRegistry#singletonsCurrentlyInCreation。在bean创建前会将bean添加,bean创建结束后将bean移除。这一点我们在前篇有过提及。

满足上述三个条件后,则会 调用 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 方法。这个方法作用是将正在创建的bean缓存起来,主要目的还是用来解决循环依赖的问题。

详细代码如下:

    // 对一系列缓存map 做处理。在 singletonFactories 中保存 ObjectFactory 类型,进行提前暴露
    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
            Assert.notNull(singletonFactory, "Singleton factory must not be null");
            synchronized (this.singletonObjects) {
                    // 如果singletonObjects不存在(bean未创建成功)
                    if (!this.singletonObjects.containsKey(beanName)) {
                            this.singletonFactories.put(beanName, singletonFactory);
                            this.earlySingletonObjects.remove(beanName);
                            this.registeredSingletons.add(beanName);
                    }
            }
    }
    
    ...
    // 给调用者一次机会,主要就是调用了SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference 方法。将getEarlyBeanReference  方法的返回值作为提前暴露的对象。
    // 我们可以通过实现 getEarlyBeanReference  方法来替代Spring提前暴露的对象
    // Aop 就是在这里将 Advice 动态织入bean中,若没有bean则直接返回bean,不做任何处理
    protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
            Object exposedObject = bean;
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                    for (BeanPostProcessor bp : getBeanPostProcessors()) {
                            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                            }
                    }
            }
            return exposedObject;
    }

该方法中 getEarlyBeanReference 调用了后处理器的方法,可用于用户自己扩展替换Spring生成的提前暴露的对象 :

  • SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference (Object bean, String beanName);

4.3.4 populateBean

见名知意,下面这个方法是用来属性注入的。 populateBean 方法则是对bean 属性的注入,上面的 createBeanInstance 方法创建了 bean,但是其内部属性并没有注入,比如通过 @Autowired 注解注入的变量属性,此时还为null,需要对这种属性进行注入,这一步就是完成这种功能。

    	populateBean(beanName, mbd, instanceWrapper);

在这里方法里按照如下顺序调用了后处理器

  • InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation : 返回true 才会调用下面两个方法

    • InstantiationAwareBeanPostProcessor.postProcessProperties : 进行属性的注入。
    • InstantiationAwareBeanPostProcessor.postProcessPropertyValues : 已过时 详细的代码分析后面分析。

4.3.5 initializeBean

到达这一步,其实bean已经创建结束了,这一步是完成最后的功能,提供一些功能的实现,如Aware 接口的实现, init-method、InitializingBean属性等。

    	exposedObject = initializeBean(beanName, exposedObject, mbd);

详情后面分析

4.3.6 循环依赖检查

Spring 循环依赖的解决仅对单例且非构造函数构造的形式有效,对于原型模式的bean,Spring直接抛出异常,在这个步骤中会检测已经加载的bean 是否已经出现了循环依赖,并判断是否需要抛出异常。

    // earlySingletonExposure 为true 说明要校验循环依赖的问题
    if (earlySingletonExposure) {
            // 调用了 getSingleton 方法获取缓存中的对象,这里注意传递的false。
            Object earlySingletonReference = getSingleton(beanName, false);
            // 如果 earlySingletonReference  不为空,则说明存在循环依赖
            if (earlySingletonReference != null) {
                    // 如果缓存的对象 exposedObject == bean,直接赋值之前暴露出来的bean
                    // 这里
                    if (exposedObject == bean) {
                            exposedObject = earlySingletonReference;
                    }
                    // allowRawInjectionDespiteWrapping 默认false && beanName 被其他bean依赖
                    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                            // 获取依赖于 当前bean的 beanName
                            String[] dependentBeans = getDependentBeans(beanName);
                            Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                            for (String dependentBean : dependentBeans) {
                                    // 
                                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                                            actualDependentBeans.add(dependentBean);
                                    }
                            }
                            // 如果 actualDependentBeans 不为空,则抛出循环依赖的异常
                            if (!actualDependentBeans.isEmpty()) {
                                    throw new BeanCurrentlyInCreationException(beanName,
                                                    "Bean with name '" + beanName + "' has been injected into other beans [" +
                                                    StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                                    "] in its raw version as part of a circular reference, but has eventually been " +
                                                    "wrapped. This means that said other beans do not use the final version of the " +
                                                    "bean. This is often the result of over-eager type matching - consider using " +
                                                    "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                            }
                    }
            }
    }
    
    ...
    // 上面调用的 getSingleton 方法。可以知道这里传递的 allowEarlyReference 为false。
    // 因为当前bean在进行循环创建的时候,就已经将 bean缓存到 earlySingletonObjects 中了
    // DCL
    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
       // Quick check for existing instance without full singleton lock
       // 检查单例缓存池 中有没有
       Object singletonObject = this.singletonObjects.get(beanName);  // 以及缓存
       // 如果当前bean正在创建中,而且缓存中没有则继续
       // 单例缓存中没有对象 && 当前单例bean正在创建中,这是为了解决循环依赖的问题
       if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
          // 如果此时bean正在加载(bean 在 earlySingletonObjects 中),则直接将singletonObject 返回。
          singletonObject = this.earlySingletonObjects.get(beanName); // 二级缓存
          // allowEarlyReference = true 才会允许循环依赖
          if (singletonObject == null && allowEarlyReference) {
             // 如果单例缓存中不存在该bean,则加锁进行接下来的处理
             synchronized (this.singletonObjects) {
                // Consistent creation of early reference within full singleton lock
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                   singletonObject = this.earlySingletonObjects.get(beanName);
                   if (singletonObject == null) {
                      // 当某些方法需要提前初始化的时候则会调用addSingletonFactory
                      // 将对应的ObjectFactory初始化策略存储在singletonFactories中
                      ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);  // 三级缓存
                      if (singletonFactory != null) {
                         // 调用预先设定的getObject方法
                         singletonObject = singletonFactory.getObject();
                         // 记录在缓存中,earlySingletonObjects 和 singletonFactories互斥
                         this.earlySingletonObjects.put(beanName, singletonObject);
                         this.singletonFactories.remove(beanName);
                      }
                   }
                }
             }
          }
       }
       return singletonObject;
    }
    ...
    // 删除给定bean名称的单例实例(如果有的话),但前提是该类型仅用于类型检查以外的用途。
    protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
            if (!this.alreadyCreated.contains(beanName)) {
                    removeSingleton(beanName);
                    return true;
            }
            else {
                    return false;
            }
    }
    ...
    protected void removeSingleton(String beanName) {
            synchronized (getSingletonMutex()) {
                    super.removeSingleton(beanName);
                    this.factoryBeanObjectCache.remove(beanName);
            }
    }
    ...
    // super.removeSingleton(beanName); 如下
    protected void removeSingleton(String beanName) {
            synchronized (this.singletonObjects) {
                    this.singletonObjects.remove(beanName);
                    this.singletonFactories.remove(beanName);
                    this.earlySingletonObjects.remove(beanName);
                    this.registeredSingletons.remove(beanName);
            }
    }

关于这一段的逻辑参考 : blog.csdn.net/qq_18297675…

整个逻辑如下:

  1. getSingleton(beanName, false); : 从缓存中获取缓存对象,这传递的false, 直接从 earlySingletonObjects 中获取循环依赖的对象 earlySingletonReference
  2. 如果 earlySingletonReference == bean ,说明bean没有被修改,直接赋值即可。
  3. 如果 earlySingletonReference != bean ,那么说明 在 下面的代码中,bean被修改了
        populateBean(beanName, mbd, instanceWrapper);
        exposedObject = initializeBean(beanName, exposedObject, mbd);

此时需获取依赖于当前bean的 dependentBeans。如果dependentBeans 中有已经创建好的,那么则抛出异常

4.3.7 registerDisposableBeanIfNecessary

这一步的目的是实现 destory-method 属性,如果bean配置了该属性,则需要注册以便在销毁时调用。

详细代码如下:

    protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
            AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
            if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
                    if (mbd.isSingleton()) {
                            // Register a DisposableBean implementation that performs all destruction
                            // work for the given bean: DestructionAwareBeanPostProcessors,
                            // DisposableBean interface, custom destroy method.
                            // 单例模式下注册需要销毁的bean,此方法会处理实现DisposableBean的bean
                            // 并且对所有的bean使用 DestructionAwareBeanPostProcessor 处理 DisposableBean DestructionAwareBeanPostProcessor
                            registerDisposableBean(beanName,
                                            new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
                    }
                    else {
                            // A bean with a custom scope...
                            // 自定义 scope 的处理
                            Scope scope = this.scopes.get(mbd.getScope());
                            if (scope == null) {
                                    throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
                            }
                            scope.registerDestructionCallback(beanName,
                                            new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
                    }
            }
    }

篇幅有限,剩下的几个核心方法,下一篇文章阐述,敬请期待。

参考文章

Spring5源码注释github地址
Spring源码深度解析(第2版)
spring源码解析
Spring源码深度解析笔记
Spring注解与源码分析
Spring注解驱动开发B站教程