面试阿里被问到Spring的Bean实例化的过程,轻松拿捏

前言

上一篇文章Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理已经完成了对IoC容器启动方法也就是refresh()方法的简单分析。但是之前的分析在对容器实例化Bean的过程的略过了,留到了这后续的文章分析,所以这篇文章会对Bean的实例化过程做一个介绍。

首先来理一下本文的思路:关键词是实例化。由于Spring是利用反射实现的实例化,脑子里先简单想一下Java里利用发射实例化一个对象需要哪些步骤和操作。毫无疑问,我们首先要知道对象的class,接着需要确定使用什么构造函数以及确定构造函数的参数等。利用这些已经基本可以实现一个对象的实例化,当然实际上需要的东西可能更多更复杂,这里只是举个例子。那么需要的这些信息可以去哪里提取呢?对Spring有了解的可能都马上能想到BeanDefinition,这是一份原料表,里面有我们构造一个实例化对象所需的所有参数。如果不太理解这个定义,可以参考一下上篇文章的例子。

如果不清楚BeanDefinition是从哪里来的以及不清楚如何定义的,可以参考之前的文章Spring Ioc源码分析系列--Ioc源码入口分析的关键实现系列方法loadBeanDefinitions ()。这篇文章讲解注册的时候只是说了注册到容器里,并没有说明具体是注册到了哪里,这里点明一下,所谓讲BeanDefinition注册到容器里,就是将BeanDefinition放入到容器的一个Map里,具体是注册到了DefaultListableBeanFactorybeanDefinitionMap属性里,beanName会保存到beanDefinitionNames属性里,这是个list集合,里面的beanName会保持注册时候的顺序。

实例化的开始就是从遍历所有的beanName开始,话不多说,开始分析吧。

源码分析

bean实例化入口

还记得实例化入口的方法名吗?回忆一下,算了,反正也不会有人记得。是beanFactory.preInstantiateSingletons(),具体实现是在DefaultListableBeanFactory类里。

跟进代码查看,可以看到,这段代码分为两部分,第一个for循环用于先实例化对象,第二个for循环完成一些实例化之后的回调操作。我们先来看第一个for循环,首先是遍历所有的beanNames获取BeanDefinition,然后根据工厂bean非工厂bean进行相应处理,最后调用getBean(beanName)实例化对象。注意这里实例化的是非抽象的、单例的并且是非懒加载的bean,这个前提非常重要。

public void preInstantiateSingletons() throws BeansException {
  if (logger.isTraceEnabled()) {
   logger.trace("Pre-instantiating singletons in " + this);
  }

  // Iterate over a copy to allow for init methods which in turn register new bean definitions.
  // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
  // 所有bd的名称
  List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

  // Trigger initialization of all non-lazy singleton beans...
  // 遍历所有bd,一个个进行创建
  for (String beanName : beanNames) {
   // 获取到指定名称对应的bd
   RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
   // 对不是延迟加载的单例的Bean进行创建
   if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    // 判断是否是一个FactoryBean
    if (isFactoryBean(beanName)) {
     // 如果是一个factoryBean的话,先创建这个factoryBean,创建factoryBean时,需要在beanName前面拼接一个&符号
     Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
     if (bean instanceof FactoryBean) {
      final FactoryBean<?> factory = (FactoryBean<?>) bean;
      boolean isEagerInit;
      if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
       isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
           ((SmartFactoryBean<?>) factory)::isEagerInit,
         getAccessControlContext());
      }
      else {
       // 判断是否是一个SmartFactoryBean,并且不是懒加载的,就意味着,在创建了这个factoryBean之后要立马调用它的getObject方法创建另外一个Bean
       isEagerInit = (factory instanceof SmartFactoryBean &&
         ((SmartFactoryBean<?>) factory).isEagerInit());
      }
      if (isEagerInit) {
       getBean(beanName);
      }
     }
    }
    else {
     // 不是factoryBean的话,我们直接创建就行了
     getBean(beanName);
    }
   }
  }

  // Trigger post-initialization callback for all applicable beans...
  // 在创建了所有的Bean之后,遍历为所有适用的 bean 触发初始化后回调,也就是这里会对延迟初始化的bean进行加载...
  for (String beanName : beanNames) {
   // 这一步其实是从缓存中获取对应的创建的Bean,这里获取到的必定是单例的
   Object singletonInstance = getSingleton(beanName);
   // 判断是否是一个SmartInitializingSingleton,
   // 最典型的就是我们之前分析过的EventListenerMethodProcessor,
   // 在这一步完成了对已经创建好的Bean的解析,会判断其方法上是否有 @EventListener注解,
   // 会将这个注解标注的方法通过EventListenerFactory转换成一个事件监听器并添加到监听器的集合中
   if (singletonInstance instanceof SmartInitializingSingleton) {
    final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
    if (System.getSecurityManager() != null) {
     AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
      smartSingleton.afterSingletonsInstantiated();
      return null;
     }, getAccessControlContext());
    }
    else {
     smartSingleton.afterSingletonsInstantiated();
    }
   }
  }
 }

获取BeanDefinition

首先跟进getMergedLocalBeanDefinition(beanName)方法,这里首先会尝试从mergedBeanDefinitions里去获取,这个mergedBeanDefinitions存放着已经合并过的BeanDefinition,获取不到再真正调用getMergedBeanDefinition(beanName, getBeanDefinition(beanName))去获取。

/**
  * Return a merged RootBeanDefinition, traversing the parent bean definition
  * if the specified bean corresponds to a child bean definition.
  *
  * 返回一个合并的 RootBeanDefinition,如果指定的 bean 对应于子 bean 定义,则遍历父 bean 定义。
  *
  * @param beanName the name of the bean to retrieve the merged definition for
  * @return a (potentially merged) RootBeanDefinition for the given bean
  * @throws NoSuchBeanDefinitionException if there is no bean with the given name
  * @throws BeanDefinitionStoreException in case of an invalid bean definition
  */
 protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
  // Quick check on the concurrent map first, with minimal locking.
  // 首先检查 mergedBeanDefinitions ,最小程度影响并发性能
  RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
  if (mbd != null && !mbd.stale) {
   return mbd;
  }
  return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
 }

先看getBeanDefinition(beanName),这个方法就是简单的去beanDefinitionMap里获取BeanDefinition,如果获取不到,就抛出异常。beanDefinitionMap就是上面说到的BeanDefinition存放的地方。

public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
  BeanDefinition bd = this.beanDefinitionMap.get(beanName);
  if (bd == null) {
   if (logger.isTraceEnabled()) {
    logger.trace("No bean named '" + beanName + "' found in " + this);
   }
   throw new NoSuchBeanDefinitionException(beanName);
  }
  return bd;
 }

接下来就进入到getMergedBeanDefinition()方法获取BeanDefinition,为啥要从beanDefinitionMap获取了还进行一个merged获取呢?这是因为Bean有层次关系,子类需要合并父类的属性方法等,所以要进行一次合并,合并完成后会放入到mergedBeanDefinitions里,功能和属性名区分度还是十分贴切的🐕。

跟进方法,代码已添加注释,比较简单,跟着看看就行。

/**
  * Return a RootBeanDefinition for the given top-level bean, by merging with
  * the parent if the given bean's definition is a child bean definition.
  *
  * 如果给定 bean 的定义是子 bean 定义,则通过与父级合并返回给定顶级 bean 的 RootBeanDefinition。
  *
  * @param beanName the name of the bean definition
  * @param bd the original bean definition (Root/ChildBeanDefinition)
  * @return a (potentially merged) RootBeanDefinition for the given bean
  * @throws BeanDefinitionStoreException in case of an invalid bean definition
  */
 protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
   throws BeanDefinitionStoreException {

  return getMergedBeanDefinition(beanName, bd, null);
 }

 /**
  * Return a RootBeanDefinition for the given bean, by merging with the
  * parent if the given bean's definition is a child bean definition.
  *
  * 如果给定 bean 的定义是子 bean 定义,则通过与父合并返回给定 bean 的 RootBeanDefinition
  *
  * @param beanName the name of the bean definition
  * @param bd the original bean definition (Root/ChildBeanDefinition)
  * @param containingBd the containing bean definition in case of inner bean,
  * or {@code null} in case of a top-level bean
  *    如果是内部 bean,则包含 bean 定义,如果是顶级 bean,则为 {@code null}
  * @return a (potentially merged) RootBeanDefinition for the given bean
  * @throws BeanDefinitionStoreException in case of an invalid bean definition
  */
 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;
    mbd = null;
    if (bd.getParentName() == null) {
     // Use copy of given root bean definition.
     // 使用给定根 bean 定义的副本。
     if (bd instanceof RootBeanDefinition) {
      mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
     }
     else {
      mbd = new RootBeanDefinition(bd);
     }
    }
    else {
     // Child bean definition: needs to be merged with parent.
     // 子bean定义:需要与父合并。
     BeanDefinition pbd;
     try {
      String parentBeanName = transformedBeanName(bd.getParentName());
      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 an AbstractBeanFactory 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(RootBeanDefinition.SCOPE_SINGLETON);
    }

    // A bean contained in a non-singleton bean cannot be a singleton itself.
    // Let's correct this on the fly here, since this might be the result of
    // parent-child merging for the outer bean, in which case the original inner bean
    // definition will not have inherited the merged outer bean's singleton status.
    // 包含在非单例 bean 中的 bean 本身不能是单例。
    // 让我们在这里即时纠正这个问题,因为这可能是外部 bean 的父子合并的结果,
    // 在这种情况下,原始内部 bean 定义将不会继承合并的外部 bean 的单例状态。
    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)
    // 暂时缓存合并的 bean 定义(它可能稍后仍会重新合并以获取元数据更改)
    if (containingBd == null && isCacheBeanMetadata()) {
     this.mergedBeanDefinitions.put(beanName, mbd);
    }
   }
   if (previous != null) {
    copyRelevantMergedBeanDefinitionCaches(previous, mbd);
   }
   return mbd;
  }
创建Bean

获取BeanDefinition完成后,接下来就调用getBean(beanName)进行bean的实例化了。当然这里的创建还是分了工厂Bean和非工厂Bean两个逻辑,如果是一个工厂Bean,那么getBean(beanName)这一步只会创建一个工厂Bean,接下来会通过isEagerInit参数判断是否需要初始化工厂Bean的对象,如果需要,再调用getBean(beanName)去立马获取工厂Bean需要生产的对象。不是工厂Bean的话,直接一步到位创建对象了,少一分曲折。

跟进代码查看,可以看到真正的执行代码的是在doGetBean()方法里。跟进doGetBean()方法,发现代码非常的长,这里我会把这个方法切分成几块去解析。

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

由于代码量比较大,这里贴一张图,展示各个部分间的作用,然后对每个部分进行逐步分析。

745157af7335738855b79a7e0fac6fd3.png
img

看起来是不是很简单,其实每一部分都包含了大量的细节操作,先来看第一步的名称转换,这个比较简单。

名称转换

这一步就是把&开头的name转换成不带&name

/**
  * Return the bean name, stripping out the factory dereference prefix if necessary,
  * and resolving aliases to canonical names.
  *
  * 返回 bean 名称,必要时去除工厂取消引用前缀,并将别名解析为规范名称。
  *
  * @param name the user-specified name
  * @return the transformed bean name
  */
 protected String transformedBeanName(String name) {
  return canonicalName(BeanFactoryUtils.transformedBeanName(name));
 }

可以看到这里会有个循环去处理,带有多个&的都会被去掉。

/**
  * Return the actual bean name, stripping out the factory dereference
  * prefix (if any, also stripping repeated factory prefixes if found).
  *
  * 返回实际的 bean 名称,去除工厂取消引用前缀(如果有,也去除重复的工厂前缀,如果找到)。
  *
  * @param name the name of the bean
  * @return the transformed name
  * @see BeanFactory#FACTORY_BEAN_PREFIX
  */
 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;
  });
 }

确定名称,一个Bean可能会有很多委派的别名,这个时候需要确定最根本的那个name,用这个最根本的name来作为beanName去进行后续的操作,这里同样有个循环去处理,因为别名也会有多重,会存在别名的别名这种情况。

/**
  * Determine the raw name, resolving aliases to canonical names.
  * 确定原始名称,将别名解析为规范名称。
  * @param name the user-specified name
  * @return the transformed name
  */
 public String canonicalName(String name) {
  String canonicalName = name;
  // Handle aliasing...
  // 处理别名...
  String resolvedName;
  do {
   // 可能会有别名层层嵌套的情况,所以需要获取到最终的名称
   resolvedName = this.aliasMap.get(canonicalName);
   if (resolvedName != null) {
    canonicalName = resolvedName;
   }
  }
  while (resolvedName != null);
  return canonicalName;
 }
从容器缓存中获取Bean

在上一步中我们已经获取到了真正的beanName,那么接下来,就可以利用这个beanName到容器的缓存中尝试获取bean,如果之前已经创建过,这里就可以直接获取到bean。这里的缓存包括三级,但是这三级缓存并不是包含的关系,而是一种互斥的关系,一个bean无论处于何种状态,它在同一时刻只能处于某个缓存当中。

跟进getSingleton(beanName)方法代码。

public Object getSingleton(String beanName) {
  return getSingleton(beanName, true);
 }

可以看到这里默认给多了一个参数为true,这参数为allowEarlyReference,用来控制是否允许循环依赖。方法代码注释比较详细,就是逐个缓存去获取,跟着看一下问题不大。第一次进来肯定是获取不到任何东西的,所以这里会返回null

/**
  * 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>检查已经实例化的单例,并允许提前引用当前创建的单例(解决循环引用)。
  *
  * @param beanName the name of the bean to look for 要查找的 bean 的名称
  * @param allowEarlyReference whether early references should be created or not 是否应创建早期引用
  * @return the registered singleton object, or {@code null} if none found 注册的单例对象,如果没有找到则为 {@code null}
  */
 @Nullable
 protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  // 检测一级缓存中是否存在实例
  Object singletonObject = this.singletonObjects.get(beanName);
  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
   // 如果为空,则锁定全局变量进行处理
   synchronized (this.singletonObjects) {
    // 从二级缓存 earlySingletonObjects 中获取
    singletonObject = this.earlySingletonObjects.get(beanName);
    // 二级缓存中没有,并且 allowEarlyReference = true 允许提前创建早期引用,则到三级缓存中获取
    // 早期引用一般是用来指向需要经过代理的bean或者是需要延迟初始化的bean
    if (singletonObject == null && allowEarlyReference) {
     // 当某些方法需要提前初始化的时候,则会调用addSingletonFactory方法
     // 将对应的objectFactory初始化策略存储在singletonFactories
     ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
     if (singletonFactory != null) {
      // 这里的实现是一个lambada表达式,具体的实现有很多种
      // 调用预先设定的getObject方法,也就是调用之前加入的 getEarlyBeanReference()方法
      // 此表达式是在 doCreateBean() 方法中调用 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)) 加入的
      singletonObject = singletonFactory.getObject();
      // 将bean加入二级缓存中
      this.earlySingletonObjects.put(beanName, singletonObject);
      // 同时从三级缓存中将bean移除,也就是移除一个ObjectFactory,对应为一个lambada表达式
      this.singletonFactories.remove(beanName);
     }
    }
   }
  }
  return singletonObject;
 }
缓存存在bean

这里讲解的是截图的第三部分,代码是第260行到276行左右。

if (sharedInstance != null && args == null) {
   // 省略部分日志...
   // 如果直接从单例池中获取到了这个 bean(sharedInstance),我们能直接返回吗?
   // 当然不能,因为获取到的 Bean 可能是一个 factoryBean,
   // 如果我们传入的 name 是 & + beanName 这种形式的话,
   // 那是可以返回的,但是我们传入的更可能是一个 beanName,
   // 那么这个时候 Spring 就还需要调用这个 sharedInstance 的 getObject 方法来创建真正被需要的 Bean
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  }

可以看到,去除日志后,只剩下一个主要的方法,跟进getObjectForBeanInstance()代码查看。可以看到这里会进行一些类型的判断,会尝试从缓存获取,最后会调用getObjectFromFactoryBean方法从FactoryBean里获取实例对象。

/**
  * Get the object for the given bean instance, either the bean
  * instance itself or its created object in case of a FactoryBean.
  *
  * 获取给定 bean 实例的对象,bean 实例本身或其创建的对象(如果是 FactoryBean)。
  *
  * @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.
  // 如果指定的name是工厂相关(以&为前缀)且 beanInstance又不是FactoryBean类型则验证不通过
  if (BeanFactoryUtils.isFactoryDereference(name)) {
   if (beanInstance instanceof NullBean) {
    return beanInstance;
   }
   if (!(beanInstance instanceof FactoryBean)) {
    throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
   }
   if (mbd != null) {
    mbd.isFactoryBean = true;
   }
   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 实例,除非调用者实际上想要一个对工厂的引用。
  // 如果是普通bean,直接返回了
  if (!(beanInstance instanceof FactoryBean)) {
   return beanInstance;
  }

  //加载factoryBean
  Object object = null;
  if (mbd != null) {
   mbd.isFactoryBean = true;
  }
  else {
   //尝试从缓存中获取
   object = getCachedObjectForFactoryBean(beanName);
  }
  if (object == null) {
   // Return bean instance from factory.
   // 到这里可以确定 beanInstance 一定是 FactoryBean 类型
   FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
   // Caches object obtained from FactoryBean if it is a singleton.
   // 如果是单例,则缓存从 FactoryBean 获得的对象。
   // containsBeanDefinition 检测 beanDefinitionMap 中也就是在所有已经加载的类中检测是否定义 beanName
   if (mbd == null && containsBeanDefinition(beanName)) {
    // 将存储XML文件的 GenericBeanDefinition 转换为 RootBeanDefinition,如果指定的 beanName 是子 bean 的话
    // 会同时合并父类的相关属性
    mbd = getMergedLocalBeanDefinition(beanName);
   }
   //是否是用用户自己定义的还是用程序本身定义的
   boolean synthetic = (mbd != null && mbd.isSynthetic());
   object = getObjectFromFactoryBean(factory, beanName, !synthetic);
  }
  return object;
 }

跟进getObjectFromFactoryBean()方法,该方法首先也是从缓存获取,然后调用doGetObjectFromFactoryBean()真正获取bean对象,这里会区分单例和原型分别去获取,单例获取完成后会放入缓存,原型则每次都新建,所以原型bean的创建前前后后会省略很多步骤。获取完成后根据shouldPostProcess判断是否需要后置处理,从而执行BeanPostProcessor#postProcessAfterInitialization()后置处理器的方法,最后将对象放入缓存中。这些处理思路跟我们平时写业务代码的思路也是非常类似的,可以互相借鉴一下。

/**
  * Obtain an object to expose from the given FactoryBean.
  *
  * 从给定的 FactoryBean 中获取要公开的对象。
  *
  * @param factory the FactoryBean instance
  * @param beanName the name of the bean
  * @param shouldPostProcess whether the bean is subject to post-processing bean是否经过后处理
  * @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) {
  //如果是单例的话
  if (factory.isSingleton() && containsSingleton(beanName)) {
   //加锁,保证单例
   synchronized (getSingletonMutex()) {
    //先从缓存中获取
    Object object = this.factoryBeanObjectCache.get(beanName);
    if (object == null) {
     //从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)
     // 如果在上面的 getObject() 调用期间尚未放置,则仅进行后处理和存储(例如,由于自定义 getBean 调用触发的循环引用处理)
     Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
     if (alreadyThere != null) {
      object = alreadyThere;
     }
     else {
      if (shouldPostProcess) {
       if (isSingletonCurrentlyInCreation(beanName)) {
        // Temporarily return non-post-processed object, not storing it yet..
        // 暂时返回非后处理对象,暂不存储..
        return object;
       }
       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 {
        afterSingletonCreation(beanName);
       }
      }
      if (containsSingleton(beanName)) {
       this.factoryBeanObjectCache.put(beanName, object);
      }
     }
    }
    return object;
   }
  }
  else {
   // 从 FactoryBean 获取对象
   Object object = doGetObjectFromFactoryBean(factory, beanName);
   if (shouldPostProcess) {
    try {
     // 后置处理从 FactoryBean 获取的对象
     object = postProcessObjectFromFactoryBean(object, beanName);
    }
    catch (Throwable ex) {
     throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
    }
   }
   return object;
  }
 }

跟进doGetObjectFromFactoryBean()方法,这个方法就更简单了,就是调用工厂bean的getObject()方法返回bean。

/**
  * Obtain an object to expose from the given FactoryBean.
  *
  * 从给定的 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) {
    // 省略部分代码...
   }
   else {
    //直接调用factory.getObject()方法
    object = factory.getObject();
   }
  }
  catch (Throwable ex) {
   // 省略部分异常处理...
  }

  // Do not accept a null value for a FactoryBean that's not fully
  // initialized yet: Many FactoryBeans just return null then.
  // 不要为尚未完全初始化的 FactoryBean 接受 null 值:许多 FactoryBean 只返回 null。
  if (object == null) {
   if (isSingletonCurrentlyInCreation(beanName)) {
    throw new BeanCurrentlyInCreationException(
      beanName, "FactoryBean which is currently in creation returned null from getObject");
   }
   object = new NullBean();
  }
  return object;
 }

到这里,图片上的第三部分过完了。接下来是第四步。

真正进入创建Bean的流程

经过前面这么多铺垫,才真正走到了创建Bean的地方。这里会比较复杂且啰嗦,需要点耐心看完。

这部分代码如下,可以跟着注释看下这段代码。这里先对原型类型的循环依赖进行校验,原型bean出现循环依赖直接抛异常。然后回去父容器里获取,紧接着又处理了被@DependsOn注解标注的依赖,然后再进行bean的创建。

// Fail if we're already creating this bean instance:
   // We're assumably within a circular reference.
   // 在缓存中获取不到这个Bean
   // 原型下的循环依赖直接报错
   if (isPrototypeCurrentlyInCreation(beanName)) {
    throw new BeanCurrentlyInCreationException(beanName);
   }

   // Check if bean definition exists in this factory.
   // 核心要义,找不到我们就从父容器中再找一次
   // 我们简单的示例是不会有父容器存在的,这一块可以理解为递归到父容器中查找,跟在当前容器查找逻辑是类似的
   BeanFactory parentBeanFactory = getParentBeanFactory();
   if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    // Not found -> check parent.
    // 从父容器获取,根据不同的参数调用不同的方法
    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标记为正在创建中,其实就是将这个beanName放入到alreadyCreated这个set集合中
   if (!typeCheckOnly) {
    markBeanAsCreated(beanName);
   }

   try {
    // 为什么这里需要再获取一次,因为经过之前的操作,RootBeanDefinition 可能已经发生了改变,
    // 其中的 stale 属性可能已经设为 true,这时需要去容器里重新获取,而不是直接从缓存中返回
    // 例如上面的 markBeanAsCreated() 方法就会修改 stale 属性
    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    // 检查合并后的bd是否是abstract,这个检查现在已经没有作用了,必定会通过
    checkMergedBeanDefinition(mbd, beanName, args);

    // Guarantee initialization of beans that the current bean depends on.
    // @DependsOn注解标注的当前这个Bean所依赖的bean名称的集合,
    // 就是说在创建当前这个Bean前,必须要先将其依赖的Bean先完成创建
    String[] dependsOn = mbd.getDependsOn();
    if (dependsOn != null) {
     // 遍历所有申明的依赖
     for (String dep : dependsOn) {
      // 如果这个bean所依赖的bean又依赖了当前这个bean,出现了循环依赖,直接报错
      if (isDependent(beanName, dep)) {
       throw new BeanCreationException(mbd.getResourceDescription(), beanName,
         "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
      }
      // 注册bean跟其依赖的依赖关系,key为依赖,value为依赖所从属的bean
      registerDependentBean(dep, beanName);
      try {
       // 先创建其依赖的Bean
       getBean(dep);
      }
      catch (NoSuchBeanDefinitionException ex) {
       throw new BeanCreationException(mbd.getResourceDescription(), beanName,
         "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
      }
     }
    }

    // Create bean instance.创建bean实例
    // 我们目前只分析单例的创建,单例看懂了,原型自然就懂了
    if (mbd.isSingleton()) {
     // 这里再次调用了 getSingleton() 方法,
     // 这里跟方法开头调用的 getSingleton() 的区别在于,
     // 这个方法多传入了一个 ObjectFactory 类型的参数,
     // 这个 ObjectFactory 会返回一个 Bean
     sharedInstance = getSingleton(beanName, () -> {
      try {
       return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
       // Explicitly remove instance from singleton cache: It might have been put there
       // eagerly by the creation process, to allow for circular reference resolution.
       // Also remove any beans that received a temporary reference to the bean.
       // 从单例缓存中显式删除实例:它可能已被创建过程提前地放在那里,以允许循环引用解析。
       // 还要删除任何接收到对 bean 的临时引用的 bean。
       destroySingleton(beanName);
       throw ex;
      }
     });
     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }

    else if (mbd.isPrototype()) {
     // It's a prototype -> create a new instance.
     Object prototypeInstance = null;
     try {
      beforePrototypeCreation(beanName);
      prototypeInstance = createBean(beanName, mbd, args);
     }
     finally {
      afterPrototypeCreation(beanName);
     }
     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, () -> {
       beforePrototypeCreation(beanName);
       try {
        return createBean(beanName, mbd, args);
       }
       finally {
        afterPrototypeCreation(beanName);
       }
      });
      bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
     }
     catch (IllegalStateException ex) {
      // 省略部分异常处理...
     }
    }
   }
   catch (BeansException ex) {
    cleanupAfterBeanCreationFailure(beanName);
    throw ex;
   }

其实去掉部分校验,去掉部分复杂场景下才会有的逻辑,核心代码就是getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法,这个方法是不是有点眼熟,getSingleton()有三个同名的重载方法。前两个上面已经见过,这里是第三个。

e321887982d7951371fc71a638912cfe.png
img

仔细看这段代码,singletonFactory部分传入的是个lambada表达式,里面是正常创建bean的createBean()方法。

sharedInstance = getSingleton(beanName, () -> {
      try {
       return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
       // 省略部分异常处理...
      }
     });

结合getSingleton()方法查看,该方法处理一些前置判断和后置处理后,核心的代码就是singletonFactory.getObject()方法,这里执行的就是上面传入的lambada表达式,也就是会执行到createBean(beanName, mbd, args)方法。createBean(beanName, mbd, args)又是一个很曲折的方法,简直是曲折他妈给曲折开门,曲折到家了。所以我打算下一篇Spring Ioc源码分析系列--Bean实例化过程(二)说。在创建完成后,会把bean放入单例缓存singletonObjects中。

/**
  * Return the (raw) singleton object registered under the given name,
  * creating and registering a new one if none registered yet.
  *
  * 返回以给定名称注册的(原始)单例对象,如果尚未注册,则创建并注册一个新对象。
  *
  * @param beanName the name of the bean
  * @param singletonFactory the ObjectFactory to lazily create the singleton
  * with, if necessary
  * @return the registered singleton object
  */
 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  Assert.notNull(beanName, "Bean name must not be null");
  synchronized (this.singletonObjects) {
   // 从单例池中获取,第一次进来这个地方肯定获取不到
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null) {
    // 工厂已经在销毁阶段了,这个时候还在创建Bean的话,就直接抛出异常
    if (this.singletonsCurrentlyInDestruction) {
     // 省略部分日志及异常处理...
    }
    // 在单例创建前,记录一下正在创建的单例的名称,
    // 就是把beanName放入到singletonsCurrentlyInCreation这个set集合中去
    beforeSingletonCreation(beanName);
    boolean newSingleton = false;
    boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
    if (recordSuppressedExceptions) {
     this.suppressedExceptions = new LinkedHashSet<>();
    }
    try {
     // 这里调用了singletonFactory的getObject方法,
     // 对应的实现就是在doGetBean中的那一段lambda表达式
     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) {
     // 省略部分异常处理...
    }
    finally {
     if (recordSuppressedExceptions) {
      this.suppressedExceptions = null;
     }
     // 在单例完成创建后,将beanName从singletonsCurrentlyInCreation中移除
     // 标志着这个单例已经完成了创建
     afterSingletonCreation(beanName);
    }
    if (newSingleton) {
     // 添加到单例池中
     addSingleton(beanName, singletonObject);
    }
   }
   return singletonObject;
  }
 }
进行类型转换

这里已经分析到了截图的第五部分,由于第四部分真正创建bean的部分放到了下一篇Spring Ioc源码分析系列--Bean实例化过程(二)去分析,所以到这里的时候,我们已经完成了bean的创建,这个时候,如果方法传入的requiredType不为空,那么就需要进行类型转换,如果转换失败,则抛出异常。转换成功则返回当前完成类型转换的convertedBean。至此,创建bean的流程结束,已经可以返回一个可使用的bean,是不是还是挺简单的。流程清晰。关于Spring的类型转换和校验也可以分一篇文章去分析TypeConverterConversionService在Spring体系里的前世今生,这里就不再赘述了。

// Check if required type matches the type of the actual bean instance.
  // 检查所需类型是否与实际 bean 实例的类型匹配。
  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());
   }
  }

回调SmartInitializingSingleton实现类

到这里完成单例bean的创建了,那就到了最后一步了,回调SmartInitializingSingleton#afterSingletonsInstantiated()方法,这里没啥好说的,就是第二个循环干的事。遍历所有的beanNames,然后完成回调。

这里的回调有很多实现类,比较经典的是EventListenerMethodProcessor类,该类会在这一步完成了对已经创建好的Bean的解析,会判断其方法上是否有 @EventListener注解,会将这个注解标注的方法通过EventListenerFactory转换成一个事件监听器并添加到监听器的集合中。

上面简单的分析了getBean()方法,还记得分析了什么吗?不记得了才是正常的,记住了才是怪人,忘记了可以回去翻翻,翻不翻都没事, 反正最后都会忘了。

上面分析到真正创建Bean的createBean(beanName, mbd, args)就没有继续深入去分析了,绕得太深,说不清楚。那么这一篇,就续上这个口子,去分析createBean(beanName, mbd, args)方法。

源码分析

话不多说,我们直接来到createBean(beanName, mbd, args)方法的源码。具体的实现是在AbstractAutowireCapableBeanFactory#createBean(beanName, mbd, args)里,可以直接定位到这里。

createBean()方法

跟进代码查看,这个方法也比较简单,主要分为了以下几点:

  • 初始化化Class对象。调用resolveBeanClass(mbd, beanName)方法获取class对象,这里会去解析类全限定名,最终是通过反射方法Class<?> resolvedClass = ClassUtils.forName(className, classLoader)获取Class对象。

  • 检查覆盖方法。对应的是mbdToUse.prepareMethodOverrides()方法,这里会对一些重载方法进行标记预处理,如果同方法名的方法只存在一个,那么会将覆盖标记为未重载,以避免 arg 类型检查的开销。

  • 应用后置处理器。在实例化对象前,会经过后置处理器处理,这个后置处理器的提供了一个短路机制,就是可以提前结束整个Bean的生命周期,直接从这里返回一个Bean。

  • 创建Bean。调用doCreateBean()方法进行Bean的创建,在Spring里面,带有do开头的一般是真正干活的方法,所以Ioc创建Bean到这里,才是真正要到干活的地方了。

我们庖丁解牛先把方法不同的功能按照逻辑拆分了,那接下来,就详细分析一下每个部分。

/**
  * Central method of this class: creates a bean instance,
  * populates the bean instance, applies post-processors, etc.
  *
  * 此类的中心方法:创建 bean 实例、填充 bean 实例、应用后处理器等。
  *
  * @see #doCreateBean
  */
 @Override
 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
   throws BeanCreationException {

  if (logger.isTraceEnabled()) {
   logger.trace("Creating instance of bean '" + beanName + "'");
  }
  RootBeanDefinition mbdToUse = mbd;

  // Make sure bean class is actually resolved at this point, and
  // clone the bean definition in case of a dynamically resolved Class
  // which cannot be stored in the shared merged bean definition.
  //锁定class ,根据设置的 class 属性或者根据 className 来解析 Class
  // 解析得到beanClass,为什么需要解析呢?如果是从XML中解析出来的标签属性肯定是个字符串嘛
  // 所以这里需要加载类,得到Class对象
  Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
   mbdToUse = new RootBeanDefinition(mbd);
   mbdToUse.setBeanClass(resolvedClass);
  }

  // Prepare method overrides.验证及准备覆盖的方法
  // 对XML标签中定义的lookUp属性进行预处理,
  // 如果只能根据名字找到一个就标记为非重载的,这样在后续就不需要去推断到底是哪个方法了,
  // 对于@LookUp注解标注的方法是不需要在这里处理的,
  // AutowiredAnnotationBeanPostProcessor会处理这个注解
  try {
   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.
   //给BeanPostProcessors一个露脸的机会
   // 在实例化对象前,会经过后置处理器处理
   // 这个后置处理器的提供了一个短路机制,就是可以提前结束整个Bean的生命周期,直接从这里返回一个Bean
   // 不过我们一般不会这么做,它的另外一个作用就是对AOP提供了支持,
   // 在这里会将一些不需要被代理的Bean进行标记,就本IoC系列文章而言,你可以暂时理解它没有起到任何作用
   Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
   //若果有自定义bean则直接返回了bean,不会再走后续的doCreateBean方法
   if (bean != null) {
    return bean;
   }
  }
  catch (Throwable ex) {
   throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
     "BeanPostProcessor before instantiation of bean failed", ex);
  }

  try {
   // 不存在提前初始化的操作,开始正常的创建流程
   // doXXX方法,真正干活的方法,doCreateBean,真正创建Bean的方法
   Object beanInstance = doCreateBean(beanName, mbdToUse, args);
   if (logger.isTraceEnabled()) {
    logger.trace("Finished creating instance of bean '" + beanName + "'");
   }
   return beanInstance;
  }
  catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
   // 省略部分异常..
  }
  }
 }
初始化Class对象

很显然初始化Class对象的代码在resolveBeanClass(mbd, beanName)方法里,跟进代码查看。

/**
  * Resolve the bean class for the specified bean definition,
  * resolving a bean class name into a Class reference (if necessary)
  * and storing the resolved Class in the bean definition for further use.
  *
  * 为指定的 bean 定义解析 bean 类,将 bean 类名称解析为 Class 引用(如果需要)并将解析的 Class 存储在 bean 定义中以供进一步使用。
  *
  * @param mbd the merged bean definition to determine the class for
  * @param beanName the name of the bean (for error handling purposes)
  * @param typesToMatch the types to match in case of internal type matching purposes
  * (also signals that the returned {@code Class} will never be exposed to application code)
  *       在内部类型匹配的情况下要匹配的类型(也表示返回的 {@code Class} 永远不会暴露给应用程序代码)
  * @return the resolved bean class (or {@code null} if none)
  * @throws CannotLoadBeanClassException if we failed to load the class
  */
 @Nullable
 protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
   throws CannotLoadBeanClassException {

  try {
   // 如果已经创建过,直接返回
   if (mbd.hasBeanClass()) {
    return mbd.getBeanClass();
   }
   if (System.getSecurityManager() != null) {
    return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
     doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
   }
   else {
    // 否则进行创建
    return doResolveBeanClass(mbd, typesToMatch);
   }
  }
  catch (PrivilegedActionException pae) {
   // 省略部分异常处理
  }
 }

跟进doResolveBeanClass(mbd, typesToMatch)方法,我们这里传入的typesToMatch参数对象数组为空,所以不会走排除部分类的逻辑,接下来是使用evaluateBeanDefinitionString()方法计算表达式如果传入的className有占位符,会在这里被解析,最终正常我们会走到mbd.resolveBeanClass(beanClassLoader)方法里。

private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
   throws ClassNotFoundException {

  // 获取类加载器
  ClassLoader beanClassLoader = getBeanClassLoader();
  ClassLoader dynamicLoader = beanClassLoader;
  boolean freshResolve = false;

  if (!ObjectUtils.isEmpty(typesToMatch)) {
   // When just doing type checks (i.e. not creating an actual instance yet),
   // use the specified temporary class loader (e.g. in a weaving scenario).
   // 当只是进行类型检查(即尚未创建实际实例)时,请使用指定的临时类加载器(例如在编织场景中)。
   ClassLoader tempClassLoader = getTempClassLoader();
   if (tempClassLoader != null) {
    dynamicLoader = tempClassLoader;
    freshResolve = true;
    if (tempClassLoader instanceof DecoratingClassLoader) {
     DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
     for (Class<?> typeToMatch : typesToMatch) {
      dcl.excludeClass(typeToMatch.getName());
     }
    }
   }
  }

  String className = mbd.getBeanClassName();
  if (className != null) {
   Object evaluated = evaluateBeanDefinitionString(className, mbd);
   if (!className.equals(evaluated)) {
    // A dynamically resolved expression, supported as of 4.2...
    if (evaluated instanceof Class) {
     return (Class<?>) evaluated;
    }
    else if (evaluated instanceof String) {
     className = (String) evaluated;
     freshResolve = true;
    }
    else {
     throw new IllegalStateException("Invalid class name expression result: " + evaluated);
    }
   }
   if (freshResolve) {
    // When resolving against a temporary class loader, exit early in order
    // to avoid storing the resolved Class in the bean definition.
    // 当针对临时类加载器解析时,请提前退出以避免将解析的类存储在 bean 定义中。
    if (dynamicLoader != null) {
     try {
      // 使用临时动态加载器加载 class 对象
      return dynamicLoader.loadClass(className);
     }
     catch (ClassNotFoundException ex) {
      if (logger.isTraceEnabled()) {
       logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
      }
     }
    }
    // 反射加载 class 对象
    return ClassUtils.forName(className, dynamicLoader);
   }
  }

  // Resolve regularly, caching the result in the BeanDefinition...
  // 正常解析,将结果缓存在 BeanDefinition...
  return mbd.resolveBeanClass(beanClassLoader);
 }

跟进mbd.resolveBeanClass(beanClassLoader)方法,可以看到这里就是使用反射初始化Class对象,然后缓存在BeanDefinition中。到这里,已经完成了从一个字符串的类名到一个Class对象的转换了,我们已经得到了一个可以使用的Class对象。

/**
  * Determine the class of the wrapped bean, resolving it from a
  * specified class name if necessary. Will also reload a specified
  * Class from its name when called with the bean class already resolved.
  *
  * 确定被包装的 bean 的类,必要时从指定的类名解析它。当使用已解析的 bean 类调用时,还将从其名称中重新加载指定的类。
  *
  * @param classLoader the ClassLoader to use for resolving a (potential) class name
  * @return the resolved bean class
  * @throws ClassNotFoundException if the class name could be resolved
  */
 @Nullable
 public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
  String className = getBeanClassName();
  if (className == null) {
   return null;
  }
  Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
  this.beanClass = resolvedClass;
  return resolvedClass;
 }
检查覆盖方法

初始化class对象已经完成了,接下来会去处理重载方法,处理的逻辑在mbdToUse.prepareMethodOverrides()方法里。

摘取《Spring源码深度解析》里面的一段话:

很多读者可能会不知道这个方法的作用,因为在 Spring 的配置里面根本就没有诸如 override-method 之类的配置, 那么这个方法到底是干什么用的呢? 其实在 Spring 中确实没有 override-method 这样的配置,但是在 Spring 配置中是存在 lookup-methodreplace-method 的,而这两个配置的加载其实就是将配置统一存放在 BeanDefinition 中的 methodOverrides 属性里,而这个函数的操作其实也就是针对于这两个配置的。

lookup-method通常称为获取器注入,spring in action 中对它的描述是,一种特殊的方法注入,它是把一个方法声明为返回某种类型的 bean,而实际要返回的 bean 是在配置文件里面配置的,可用在设计可插拔的功能上,解除程序依赖。 这里会对一些重载方法进行标记预处理,如果同方法名的方法只存在一个,那么会将覆盖标记为未重载,以避免 arg 类型检查的开销。

这种骚操作我们基本是不会使用的,所以简单看一下代码,浅尝辄止,有兴趣可以去翻翻。

/**
  * Validate and prepare the method overrides defined for this bean.
  * Checks for existence of a method with the specified name.
  *
  * 验证并准备为此 bean 定义的方法覆盖。检查具有指定名称的方法是否存在。
  *
  * @throws BeanDefinitionValidationException in case of validation failure
  */
 public void prepareMethodOverrides() throws BeanDefinitionValidationException {
  // Check that lookup methods exist and determine their overloaded status.
  // 检查查找方法是否存在并确定它们的重载状态。
  if (hasMethodOverrides()) {
   getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
  }
 }

可以看到这里就获取所有methodOverrides,然后遍历去调用prepareMethodOverride()方法,跟进prepareMethodOverride()方法。可以看到这里就是做个简单的标记。

/**
  * Validate and prepare the given method override.
  * Checks for existence of a method with the specified name,
  * marking it as not overloaded if none found.
  *
  * 验证并准备给定的方法覆盖。检查具有指定名称的方法是否存在,如果没有找到,则将其标记为未重载。
  *
  * @param mo the MethodOverride object to validate
  * @throws BeanDefinitionValidationException in case of validation failure
  */
 protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
  int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
  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.
   // 将覆盖标记为未重载,以避免 arg 类型检查的开销。
   mo.setOverloaded(false);
  }
 }
应用后置处理器

在实例化对象前,会经过后置处理器处理,这个后置处理器的提供了一个短路机制,就是可以提前结束整个Bean的生命周期,直接从这里返回一个Bean。不过我们一般不会这么做,它的另外一个作用就是对AOP提供了支持,在这里会将一些不需要被代理的Bean进行标记,就本IoC系列文章而言,你可以暂时理解它没有起到任何作用。

跟进代码resolveBeforeInstantiation(beanName, mbdToUse)查看。

/**
  * Apply before-instantiation post-processors, resolving whether there is a
  * before-instantiation shortcut for the specified bean.
  *
  * 应用实例化前后处理器,解析指定 bean 是否存在实例化前快捷方式。
  * 实例化前的快捷方式的意思这里可能会直接返回一个定义的代理,而不需要在把目标类初始化
  *
  * @param beanName the name of the bean
  * @param mbd the bean definition for the bean
  * @return the shortcut-determined bean instance, or {@code null} if none
  */
 //注意单词Instantiation和Initialization区别
 @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.
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    // 确定给定的 bean 的类型
    Class<?> targetType = determineTargetType(beanName, mbd);
    if (targetType != null) {
     // 提供一个提前初始化的时机,这里会直接返回一个实例对象
     bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
     if (bean != null) {
      // 如果提前初始化成功,则执行 postProcessAfterInitialization() 方法,注意单词Instantiation和Initialization区别
      // 关于这一块的逻辑,细心的一点的会发现,这里漏了实例化后置处理、初始化前置处理这两个方法。
      // 而是在提前返回对象后,直接执行了初始化后置处理器就完成了bean的整个流程,
      // 相当于是提供了一个短路的操作,不再经过Spring提供的繁杂的各种处理
      bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
     }
    }
   }
   // 设置是否已经提前实例化
   mbd.beforeInstantiationResolved = (bean != null);
  }
  return bean;
 }

跟进applyBeanPostProcessorsBeforeInstantiation()代码查看。这里只要有一个 InstantiationAwareBeanPostProcessor 返回的结果不为空,则直接返回,说明多个 InstantiationAwareBeanPostProcessor只会生效靠前的一个,注意单词Instantiation和Initialization区别

/**
  * spring bean 初始化流程
  * Bean 初始化(Initialization)
  * 1.@PoseConstruct 方法
  * 2.实现InitializingBean 接口的afterPropertiesSet()方法
  * 3.自定义初始化方法
  */
 @Nullable
 protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
  for (BeanPostProcessor bp : getBeanPostProcessors()) {
   if (bp instanceof InstantiationAwareBeanPostProcessor) {
    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
    // 如果为空,表示不作任何调整
    // 这里只要有一个 InstantiationAwareBeanPostProcessor 返回的结果不为空,则直接返回,
    // 说明多个 InstantiationAwareBeanPostProcessor 只会生效靠前的一个
    if (result != null) {
     return result;
    }
   }
  }
  return null;
 }

跟进applyBeanPostProcessorsAfterInitialization()方法,逻辑跟上面的是类似的,注意单词Instantiation和Initialization区别

@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;
 }
创建Bean

经过上面的步骤,有惊无险,我们来到了doCreateBean(beanName, mbdToUse, args)方法,这是真正进行Bean创建的地方,所以这里才是真的进入正文,前面都是打酱油走走过程。

当经历过 resolveBeforelnstantiation() 方法后,程序有两个选择 ,如果创建了代理或者说重写了 InstantiationAwareBeanPostProcessorpostProcessBeforelnstantiation() 方法并在方法 postProcessBeforelnstantiation() 中改变了 bean, 则直接返回就可以了 , 否则需要进行常规 bean 的创建。 而这常规 bean 的创建就是在 doCreateBean() 中完成的。

直接跟进doCreateBean()代码查看,代码很长,你忍一下。

/**
  * Actually create the specified bean. Pre-creation processing has already happened
  * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
  * <p>Differentiates between default bean instantiation, use of a
  * factory method, and autowiring a constructor.
  *
  * 实际创建指定的bean。
  * 此时已经进行了预创建处理,例如检查 {@code postProcessBeforeInstantiation} 回调。
  * <p>区分默认 bean 实例化、使用工厂方法和自动装配构造函数。
  *
  * @param beanName the name of the bean
  * @param mbd the merged bean definition for the bean
  * @param args explicit arguments to use for constructor or factory method invocation
  * @return a new instance of the bean
  * @throws BeanCreationException if the bean could not be created
  * @see #instantiateBean
  * @see #instantiateUsingFactoryMethod
  * @see #autowireConstructor
  */
 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
   throws BeanCreationException {
  // 这个方法真正创建了Bean,创建一个Bean会经过 创建对象 > 依赖注入 > 初始化
  // 这三个过程,在这个过程中,BeanPostProcessor会穿插执行,

  // Instantiate the bean.
  BeanWrapper instanceWrapper = null;
  if (mbd.isSingleton()) {
   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  }
  if (instanceWrapper == null) {
   //根据指定bean使用对应的策略创建新的实例,如工厂方法,构造函数自动注入,简单初始化
   // 这里真正的创建了对象
   instanceWrapper = createBeanInstance(beanName, mbd, args);
  }
  final Object bean = instanceWrapper.getWrappedInstance();
  Class<?> beanType = instanceWrapper.getWrappedClass();
  if (beanType != NullBean.class) {
   mbd.resolvedTargetType = beanType;
  }

  // Allow post-processors to modify the merged bean definition.

  // 按照官方的注释来说,这个地方是Spring提供的一个扩展点,
  // 对程序员而言,我们可以通过一个实现了MergedBeanDefinitionPostProcessor的后置处理器
  // 来修改bd中的属性,从而影响到后续的Bean的生命周期
  // 不过官方自己实现的后置处理器并没有去修改bd,
  // 而是调用了applyMergedBeanDefinitionPostProcessors方法
  // 这个方法名直译过来就是-应用合并后的bd,也就是说它这里只是对bd做了进一步的使用而没有真正的修改
  synchronized (mbd.postProcessingLock) {
   // bd只允许被处理一次
   if (!mbd.postProcessed) {
    try {
     // 应用合并后的bd
     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    }
    catch (Throwable ex) {
     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
       "Post-processing of merged bean definition failed", ex);
    }
    // 标注这个bd已经被MergedBeanDefinitionPostProcessor的后置处理器处理过
    // 那么在第二次创建Bean的时候,不会再次调用applyMergedBeanDefinitionPostProcessors
    mbd.postProcessed = true;
   }
  }

  // Eagerly cache singletons to be able to resolve circular references
  // even when triggered by lifecycle interfaces like BeanFactoryAware.
  //是否需要提前暴露mbd.isSingleton() && this.allowCircularReferences &&
  //    isSingletonCurrentlyInCreation(beanName)
  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加入工厂
   //getEarlyBeanReference对bean再一次依赖引用,主要应用SmartInstantiationAwareBeanPostProcessor
   //其中我们熟悉的AOP就是在这里将advice动态织入bean中,若没有则直接返回bean,不做任何处理
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  }

  // Initialize the bean instance.
  // 初始化实例
  Object exposedObject = bean;
  try {
   //对bean进行填充,对各个属性进行注入,可能存在依赖其他bean的属性,则会递归初始化依赖bean
   populateBean(beanName, mbd, instanceWrapper);
   //调用初始化方法
   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);
   }
  }

  if (earlySingletonExposure) {
   Object earlySingletonReference = getSingleton(beanName, false);
   //earlySingletonReference只有在检测到循环依赖的情况下才不为空
   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还没有被完全创建好
      * 也就是说还存在循环依赖
      */
     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.");
     }
    }
   }
  }

  // Register bean as disposable.
  try {
   //根据scope注册bean
   registerDisposableBeanIfNecessary(beanName, bean, mbd);
  }
  catch (BeanDefinitionValidationException ex) {
   throw new BeanCreationException(
     mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  }

  return exposedObject;
 }

分析一下这个函数设计思路:

  • 如果是单例则需要首先清除缓存。

  • 实例化 bean ,将 BeanDefinition 转换为 BeanWrapper。 转换是一个复杂的过程,但是我们可以尝试概括大致的功能,如下所示。

    • 如果存在工厂方法则使用工厂方法进行实例化。

    • 如果一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造 函数并进行实例化。

    • 如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行 bean 的实例化。

  • MergedBeanDefinitionPostProcessor的应用。 bean 合并后的处理,Autowired 注解正是通过此方法实现诸如类型的预解析。

  • 依赖处理。 在 Spring 中会有循环依赖的情况,例如,当 A 中含有 B 的属性,而 B 中又含有 A 的属性 时就会构成一个循环依赖,此时如果 A 和 B 都是单例,那么在 Spring 中的处理方式就是当创建 B 的时候,涉及自动注入 A 的步骤,并不是直接去再次创建 A,而是通过放入缓存中的 ObjectFactory 来创建实例,这样就解决了循环依赖的问题。

  • 属性填充。 将所有属性填充至 bean 的实例中。

  • 调用初始化方法。在属性填充完成后,这里会进行初始化方法的调用。

  • 循环依赖检查。 之前有提到过,在 Sping 中解决循环依赖只对单例有效,而对于 prototype 的 bean, Spring 没有好的解决办法,唯一要做的就是抛出异常。 在这个步骤里面会检测已经加载的 bean 是否 已经出现了依赖循环,并判断是再需要抛出异常。

  • 注册 DisposableBean。 如果配置了 destroy-method,这里需要注册以便于在销毁时候调用。

  • 完成创建井返回。

可以看到上面的步骤非常的繁琐,每一步骤都使用了大量的代码来完成其功能,最复杂也是最难以理解的当属循环依赖的处理,在真正进入 doCreateBean() 前我们有必要先了解下循环依赖,这里会在下一篇文章Spring Ioc源码分析系列--自动注入循环依赖的处理图文并茂去分析。

下面就按照上述的点逐个分析,接下来肯定是枯燥无味的,那开始吧。

清除factoryBeanInstanceCache缓存

首先如果是单例,会到factoryBeanInstanceCache中获取是否存在缓存,如果有这里就会从缓存里获取一个instanceWrapper,不需要再去走复杂的创建流程了。

对应代码如下:

if (mbd.isSingleton()) {
   // 你可以暂时理解为,这个地方返回的就是个null
   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  }
实例化 bean

又到了实例化bean,是不是反反复复看了很多次,到底哪里才真的创建一个bean,别慌,这里真的是真正创建bean的地方了,再套娃就是狗。

跟进createBeanInstance(beanName, mbd, args)方法。这个方法干了哪几件事?

  • 首先尝试调用obtainFromSupplier()实例化bean

  • 尝试调用instantiateUsingFactoryMethod()实例化bean

  • 根据给定参数推断构造函数实例化bean

  • 以上均无,则使用默认构造函数实例化bean

/**
  * Create a new instance for the specified bean, using an appropriate instantiation strategy:
  * factory method, constructor autowiring, or simple instantiation.
  *
  * 使用适当的实例化策略为指定的 bean 创建一个新实例:工厂方法、构造函数自动装配或简单实例化。
  *
  * @param beanName the name of the bean
  * @param mbd the bean definition for the bean
  * @param args explicit arguments to use for constructor or factory method invocation
  * @return a BeanWrapper for the new instance
  * @see #obtainFromSupplier
  * @see #instantiateUsingFactoryMethod
  * @see #autowireConstructor
  * @see #instantiateBean
  */
 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
  // Make sure bean class is actually resolved at this point.
  // 确保此时实际解析了 bean 类。
  Class<?> beanClass = resolveBeanClass(mbd, beanName);

  if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
   throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
  }
  // 通过bd中提供的instanceSupplier来获取一个对象
  // 正常bd中都不会有这个instanceSupplier属性,这里也是Spring提供的一个扩展点,但实际上不常用
  Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
  if (instanceSupplier != null) {
   return obtainFromSupplier(instanceSupplier, beanName);
  }

  //如果工厂方法不为null,则使用工厂方法初始化策略
  // bd中提供了factoryMethodName属性,那么要使用工厂方法的方式来创建对象,
  // 工厂方法又会区分静态工厂方法跟实例工厂方法
  if (mbd.getFactoryMethodName() != null) {
   return instantiateUsingFactoryMethod(beanName, mbd, args);
  }

  // Shortcut when re-creating the same bean...
  // 在原型模式下,如果已经创建过一次这个Bean了,那么就不需要再次推断构造函数了
  // 是否推断过构造函数
  boolean resolved = false;
  // 构造函数是否需要进行注入
  boolean autowireNecessary = false;
  if (args == null) {
   synchronized (mbd.constructorArgumentLock) {
    //一个类里面有多个构造函数,每个构造函数都有不同的参数,所以调用前需要根据参数锁定要调用的构造函数或工厂方法
    if (mbd.resolvedConstructorOrFactoryMethod != null) {
     resolved = true;
     autowireNecessary = mbd.constructorArgumentsResolved;
    }
   }
  }
  //如果已经解析过则使用解析好的构造函数方法,不需要再次锁定
  if (resolved) {
   if (autowireNecessary) {
    //构造函数自动注入
    return autowireConstructor(beanName, mbd, null, null);
   }
   else {
    //使用默认构造函数进行构造
    return instantiateBean(beanName, mbd);
   }
  }

  // Candidate constructors for autowiring?
  //需要根据参数解析构造函数
  Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
    mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
   //构造函数自动注入
   return autowireConstructor(beanName, mbd, ctors, args);
  }

  // Preferred constructors for default construction?
  // 默认构造的首选构造函数?
  ctors = mbd.getPreferredConstructors();
  if (ctors != null) {
   return autowireConstructor(beanName, mbd, ctors, null);
  }

  // No special handling: simply use no-arg constructor.
  //使用默认构造函数
  return instantiateBean(beanName, mbd);
 }

接下来分析以上几点,算了不分析,太长了。我在另一篇文章Spring Ioc源码分析系列--实例化Bean的几种方法会填坑。这里会详细分析上面的几点,好好把握,估计看到这都不知道啥跟啥了。

MergedBeanDefinitionPostProcessor的应用

到这里我们已经实例化了一个bean对象,但是这个bean只是个半成品,空有外壳而无内在,所以接下来的工作就是对里面的内容进行填充。那毫无疑问,按照Spring的尿性,肯定会在真正开始之前给你一个扩展点,让你还要机会在属性填充之前修改某些东西。我们经常使用的@Autowired注解就是在这里实现的,后续会写一篇Spring Ioc源码分析系列--@Autowired注解的实现原理结合源码和例子去分析它的实现。

跟进代码查看,比较简单,就是获取所有的MergedBeanDefinitionPostProcessor,然后依次执行它的postProcessMergedBeanDefinition()方法。

/**
  * Apply MergedBeanDefinitionPostProcessors to the specified bean definition,
  * invoking their {@code postProcessMergedBeanDefinition} methods.
  *
  * 将 MergedBeanDefinitionPostProcessors 应用于指定的 bean 定义,
  * 调用它们的 {@code postProcessMergedBeanDefinition} 方法。
  *
  * 可以看到这个方法的代码还是很简单的,
  * 就是调用了MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法
  *
  * @param mbd the merged bean definition for the bean
  * @param beanType the actual type of the managed bean instance
  * @param beanName the name of the bean
  * @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
  */
 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);
   }
  }
 }
依赖处理

这部分主要是为了处理循环依赖而做的准备,这里会根据earlySingletonExposure参数去判断是否允许循环依赖,如果允许,则会调用addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))方法将bean的早期引用放入到singletonFactories中。关于循环依赖的详细处理过程,可以在下一篇文章Spring Ioc源码分析系列--自动注入循环依赖的处理里看到。

// Eagerly cache singletons to be able to resolve circular references
  // even when triggered by lifecycle interfaces like BeanFactoryAware.
  //是否需要提前暴露mbd.isSingleton() && this.allowCircularReferences &&
  //    isSingletonCurrentlyInCreation(beanName)
  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加入工厂
   //getEarlyBeanReference对bean再一次依赖引用,主要应用SmartInstantiationAwareBeanPostProcessor
   //其中我们熟悉的AOP就是在这里将advice动态织入bean中,若没有则直接返回bean,不做任何处理
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  }

跟进addSingletonFactory()方法,可以看到这里会先把早期引用放入到singletonFactories三级缓存中。

/**
  * Add the given singleton factory for building the specified singleton
  * if necessary.
  *
  * 如有必要,添加给定的单例工厂以构建指定的单例。
  *
  * <p>To be called for eager registration of singletons, e.g. to be able to
  * resolve circular references.
  *
  * 被提前注册的单例Bean调用,例如用来解决循环依赖
  *
  * @param beanName the name of the bean
  * @param singletonFactory the factory for the singleton object
  */
 protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
  Assert.notNull(singletonFactory, "Singleton factory must not be null");
  synchronized (this.singletonObjects) {
   if (!this.singletonObjects.containsKey(beanName)) {
    this.singletonFactories.put(beanName, singletonFactory);
    this.earlySingletonObjects.remove(beanName);
    this.registeredSingletons.add(beanName);
   }
  }
 }

那放入到singletonFactories里面的是什么呢?从上面可以看到,这是一个lambada表达式,调用的方法的是getEarlyBeanReference(),跟进代码查看。

/**
  * Obtain a reference for early access to the specified bean,
  * typically for the purpose of resolving a circular reference.
  *
  * 获取对指定 bean 的早期访问的引用,通常用于解析循环引用。
  *
  * @param beanName the name of the bean (for error handling purposes)
  * @param mbd the merged bean definition for the bean
  * @param bean the raw bean instance
  * @return the object to expose as bean reference
  */
 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;
     // 对 bean 再一次依赖引用
     // 主要应用 SmartInstantiationAwareBeanPostProcessor, 
     // 其中我们熟知的 AOP 就是在这里将 advice 动态织入 bean 中, 若没有则直接返回 bean ,不做任何处理
     exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
    }
   }
  }
  return exposedObject;
 }
属性填充

到这里会已经完成了bean的实例化,早期引用的暴露,那接下来就到了属性填充的部分,开始对bean进行各种赋值,让一个空壳半成品bean完善成一个有血有肉的正常bean。

这里可能存在依赖其他bean的属性,则会递归初始化依赖bean。

populateBean() 函数中提供了这样的处理流程。

  • InstantiationAwareBeanPostProcessor 处理器的 postProcessAfterinstantiation 函数的应用, 此函数可以控制程序是否继续进行属性填充。

  • 根据注入类型( byName/byType ),提取依赖的 bean,并统一存入 PropertyValues 中。

  • 应用 InstantiationAwareBeanPostProcessor 处理器的 postProcessPropertyValues 方法, 对属性获取完毕填充前对属性的再次处理,典型应用是 RequiredAnnotationBeanPostProcessor 类中对属性的验证。

  • 将所有 PropertyValues 中的属性填充至 BeanWrapper 中。

跟进代码查看,又很长,这一块的代码真的是又臭又长。但是注释很详细,可以跟着看看。

/**
  * Populate the bean instance in the given BeanWrapper with the property values
  * from the bean definition.
  *
  * 使用 bean 定义中的属性值填充给定 BeanWrapper 中的 bean 实例。
  *
  * @param beanName the name of the bean
  * @param mbd the bean definition for the bean
  * @param bw the BeanWrapper with bean instance
  */
 @SuppressWarnings("deprecation")  // for postProcessPropertyValues
 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  if (bw == null) {
   if (mbd.hasPropertyValues()) {
    throw new BeanCreationException(
      mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
   }
   else {
    // Skip property population phase for null instance.
    //没有可填充的属性
    return;
   }
  }

  // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
  // state of the bean before properties are set. This can be used, for example,
  // to support styles of field injection.
  boolean continueWithPropertyPopulation = true;

  //给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前来改变 bean
  //如:可以用来支持属性注入的类型
  // 满足两个条件,不是合成类 && 存在InstantiationAwareBeanPostProcessor
  // 其中InstantiationAwareBeanPostProcessor主要作用就是作为Bean的实例化前后的钩子
  // 外加完成属性注入,对于三个方法就是
  // postProcessBeforeInstantiation  创建对象前调用
  // postProcessAfterInstantiation   对象创建完成,@AutoWired注解解析后调用
  // postProcessPropertyValues(已过期,被postProcessProperties替代) 进行属性注入
  // 下面这段代码的主要作用就是我们可以提供一个InstantiationAwareBeanPostProcessor
  // 提供的这个后置处理如果实现了postProcessAfterInstantiation方法并且返回false
  // 那么可以跳过Spring默认的属性注入,但是这也意味着我们要自己去实现属性注入的逻辑
  // 所以一般情况下,我们也不会这么去扩展
  if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
     //返回值为是否继续填充bean
     if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
      continueWithPropertyPopulation = false;
      break;
     }
    }
   }
  }

  //如果后处理器发出停止填充命令则终止后续操作
  if (!continueWithPropertyPopulation) {
   return;
  }

  // 这里其实就是判断XML是否提供了属性相关配置
  PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

  // 确认注入模型
  int resolvedAutowireMode = mbd.getResolvedAutowireMode();

  // 主要处理byName跟byType两种注入模型,byConstructor这种注入模型在创建对象的时候已经处理过了
  // 这里都是对自动注入进行处理,byName跟byType两种注入模型均是依赖setter方法
  // byName,根据setter方法的名字来查找对应的依赖,例如setA,那么就是去容器中查找名字为a的Bean
  // byType,根据setter方法的参数类型来查找对应的依赖,例如setXx(A a),就是去容器中查询类型为A的bean
  if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
   MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
   // Add property values based on autowire by name if applicable.
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    //根据名称注入
    autowireByName(beanName, mbd, bw, newPvs);
   }
   // Add property values based on autowire by type if applicable.
   if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    //根据类型注入
    autowireByType(beanName, mbd, bw, newPvs);
   }
   // pvs是XML定义的属性
   // 自动注入后,bean实际用到的属性就应该要替换成自动注入后的属性
   pvs = newPvs;
  }

  //后置处理器已经初始化
  // 检查是否有InstantiationAwareBeanPostProcessor
  // 前面说过了,这个后置处理器就是来完成属性注入的
  boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
  //需要依赖检查
  //  是否需要依赖检查,默认是不会进行依赖检查的
  boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

  // 下面这段代码有点麻烦了,因为涉及到版本问题
  // 其核心代码就是调用了postProcessProperties完成了属性注入
  PropertyDescriptor[] filteredPds = null;
  // 存在InstantiationAwareBeanPostProcessor,我们需要调用这类后置处理器的方法进行注入
  if (hasInstAwareBpps) {
   if (pvs == null) {
    pvs = mbd.getPropertyValues();
   }
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
     // 这句就是核心
     // Autowired 是通过 AutowiredAnnotationBeanPostProcessor#postProcessProperties() 实现的
     PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
     if (pvsToUse == null) {
      if (filteredPds == null) {
       // 得到需要进行依赖检查的属性的集合
       filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      }
      //对所有需要依赖检查的属性做后置处理
      //  这个方法已经过时了,放到这里就是为了兼容老版本
      pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
      if (pvsToUse == null) {
       return;
      }
     }
     pvs = pvsToUse;
    }
   }
  }
  // 需要进行依赖检查
  if (needsDepCheck) {
   if (filteredPds == null) {
    // 得到需要进行依赖检查的属性的集合
    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
   }
   //依赖检查,对应depends-on属性,3.0已经弃用此属性
   // 对需要进行依赖检查的属性进行依赖检查
   checkDependencies(beanName, mbd, filteredPds, pvs);
  }

  // 将XML中的配置属性应用到Bean上
  if (pvs != null) {
   //将属性应用到bean中
   applyPropertyValues(beanName, mbd, bw, pvs);
  }
 }

这里看到这里会根据byName或者byType方式寻找依赖,然后调用applyPropertyValues()将属性注入到BeanWrapperImpl里。

先来看autowireByName()方法,顾名思义,这里会根据属性名去获取依赖。

/**
  * Fill in any missing property values with references to
  * other beans in this factory if autowire is set to "byName".
  * 
  * 如果 autowire 设置为“byName”,则使用对该工厂中其他 bean 的引用填充任何缺少的属性值。
  * 
  * @param beanName the name of the bean we're wiring up.
  * Useful for debugging messages; not used functionally.
  * @param mbd bean definition to update through autowiring
  * @param bw the BeanWrapper from which we can obtain information about the bean
  * @param pvs the PropertyValues to register wired objects with
  */
 protected void autowireByName(
   String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

  //寻找bw中需要依赖注入的属性值
  // 得到符合下面条件的属性名称
  // 1.有setter方法
  // 2.需要进行依赖检查
  // 3.不包含在XML配置中
  // 4.不是简单类型(基本数据类型,枚举,日期等)
  // 这里可以看到XML配置优先级高于自动注入的优先级
  // 不进行依赖检查的属性,也不会进行属性注入
  String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
  for (String propertyName : propertyNames) {
   if (containsBean(propertyName)) {
    //递归初始化相关bean
    Object bean = getBean(propertyName);
    // 将自动注入的属性添加到pvs中去
    pvs.add(propertyName, bean);
    //注册依赖
    registerDependentBean(propertyName, beanName);
    if (logger.isTraceEnabled()) {
     logger.trace("Added autowiring by name from bean name '" + beanName +
       "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
    }
   }
   else {
    if (logger.isTraceEnabled()) {
     logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
       "' by name: no matching bean found");
    }
   }
  }
 }

接下来看autowireByType(),该方法会根据属性的类型去获取依赖。也比较简单明了。

/**
  * Abstract method defining "autowire by type" (bean properties by type) behavior.
  * <p>This is like PicoContainer default, in which there must be exactly one bean
  * of the property type in the bean factory. This makes bean factories simple to
  * configure for small namespaces, but doesn't work as well as standard Spring
  * behavior for bigger applications.
  * 
  * 定义“按类型自动装配”(按类型的 bean 属性)行为的抽象方法。 
  * <p>这类似于 PicoContainer 默认值,其中 bean 工厂中必须只有一个属性类型的 bean。
  * 这使得 bean 工厂易于为小型命名空间配置,但不能像标准 Spring 行为那样为大型应用程序工作。
  * 
  * @param beanName the name of the bean to autowire by type
  * @param mbd the merged bean definition to update through autowiring
  * @param bw the BeanWrapper from which we can obtain information about the bean
  * @param pvs the PropertyValues to register wired objects with
  */
 protected void autowireByType(
   String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

  // 这个类型转换器,主要是在处理@Value时需要使用
  TypeConverter converter = getCustomTypeConverter();
  if (converter == null) {
   converter = bw;
  }

  Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
  //寻找bw中需要依赖注入的属性
  // 得到符合下面条件的属性名称
  // 1.有setter方法
  // 2.需要进行依赖检查
  // 3.不包含在XML配置中
  // 4.不是简单类型(基本数据类型,枚举,日期等)
  // 这里可以看到XML配置优先级高于自动注入的优先级
  String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
  for (String propertyName : propertyNames) {
   try {
    PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
    // Don't try autowiring by type for type Object: never makes sense,
    // even if it technically is a unsatisfied, non-simple property.
    // 不要尝试为 Object 类型按类型自动装配:永远没有意义,即使它在技术上是一个不令人满意的、不简单的属性。
    if (Object.class != pd.getPropertyType()) {
     //探测指定属性的set方法
     // 这里获取到的就是setter方法的参数,因为我们需要按照类型进行注入嘛
     MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
     // Do not allow eager init for type matching in case of a prioritized post-processor.
     // 如果是PriorityOrdered在进行类型匹配时不会去匹配factoryBean
     // 如果不是PriorityOrdered,那么在查找对应类型的依赖的时候会会去匹factoryBean
     // 这就是Spring的一种设计理念,实现了PriorityOrdered接口的Bean被认为是一种
     // 最高优先级的 Bean,这一类的Bean在进行为了完成装配而去检查类型时,
     // 不去检查 factoryBean
     // 具体可以参考PriorityOrdered接口上的注释文档
     boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
     // 将参数封装成为一个依赖描述符
     // 依赖描述符会通过:依赖所在的类,字段名/方法名,依赖的具体类型等来描述这个依赖
     DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
     /**
      * 解析指定beanName的属性所匹配的值,并把解析到的属性名存储在autowiredBeanNames中,
      * 当属性存在多个封装bean时,如:
      * @Autowire
      * private List<A> list;
      * 将会找到所有匹配A类型的bean并将其注入
      * 解析依赖,这里会处理@Value注解
      * 另外,通过指定的类型到容器中查找对应的bean
      */
     Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
     if (autowiredArgument != null) {
      // 将查找出来的依赖属性添加到pvs中,后面会将这个pvs应用到bean上
      pvs.add(propertyName, autowiredArgument);
     }
     // 注册bean直接的依赖关系
     for (String autowiredBeanName : autowiredBeanNames) {
      //注册依赖
      registerDependentBean(autowiredBeanName, beanName);
      if (logger.isTraceEnabled()) {
       logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
         propertyName + "' to bean named '" + autowiredBeanName + "'");
      }
     }
     autowiredBeanNames.clear();
    }
   }
   catch (BeansException ex) {
    throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
   }
  }
 }

属性依赖都获取完了,接下来就是按部就班的进行注入了。

跟进applyPropertyValues()方法,逻辑比较复杂。但是最终是调用了反射,给对应的属性进行了赋值,这里深入的就不再展开了。

/**
  * Apply the given property values, resolving any runtime references
  * to other beans in this bean factory. Must use deep copy, so we
  * don't permanently modify this property.
  *
  * 应用给定的属性值,解析对此 bean 工厂中其他 bean 的任何运行时引用。必须使用深拷贝,所以我们不会永久修改这个属性。
  *
  * @param beanName the bean name passed for better exception information
  * @param mbd the merged bean definition
  * @param bw the BeanWrapper wrapping the target object
  * @param pvs the new property values
  */
 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
  if (pvs.isEmpty()) {
   return;
  }

  if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
   ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
  }

  MutablePropertyValues mpvs = null;
  List<PropertyValue> original;

  if (pvs instanceof MutablePropertyValues) {
   mpvs = (MutablePropertyValues) pvs;
   if (mpvs.isConverted()) {
    // Shortcut: use the pre-converted values as-is.
    // 快捷方式:按原样使用转换前的值。
    try {
     bw.setPropertyValues(mpvs);
     return;
    }
    catch (BeansException ex) {
     throw new BeanCreationException(
       mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
   }
   original = mpvs.getPropertyValueList();
  }
  else {
   original = Arrays.asList(pvs.getPropertyValues());
  }

  TypeConverter converter = getCustomTypeConverter();
  if (converter == null) {
   converter = bw;
  }
  BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

  // Create a deep copy, resolving any references for values.
  // 创建一个深拷贝副本,解析任何值的引用。
  List<PropertyValue> deepCopy = new ArrayList<>(original.size());
  boolean resolveNecessary = false;
  for (PropertyValue pv : original) {
   if (pv.isConverted()) {
    deepCopy.add(pv);
   }
   else {
    String propertyName = pv.getName();
    Object originalValue = pv.getValue();
    if (originalValue == AutowiredPropertyMarker.INSTANCE) {
     Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
     if (writeMethod == null) {
      throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
     }
     originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
    }
    // 给定一个 PropertyValue,返回一个值,必要时解析对工厂中其他 bean 的任何引用
    Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
    Object convertedValue = resolvedValue;
    boolean convertible = bw.isWritableProperty(propertyName) &&
      !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
    if (convertible) {
     convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
    }
    // Possibly store converted value in merged bean definition,
    // in order to avoid re-conversion for every created bean instance.
    // 可能将转换后的值存储在合并的 bean 定义中,以避免对每个创建的 bean 实例进行重新转换。
    if (resolvedValue == originalValue) {
     if (convertible) {
      pv.setConvertedValue(convertedValue);
     }
     deepCopy.add(pv);
    }
    else if (convertible && originalValue instanceof TypedStringValue &&
      !((TypedStringValue) originalValue).isDynamic() &&
      !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
     pv.setConvertedValue(convertedValue);
     deepCopy.add(pv);
    }
    else {
     resolveNecessary = true;
     deepCopy.add(new PropertyValue(pv, convertedValue));
    }
   }
  }
  if (mpvs != null && !resolveNecessary) {
   mpvs.setConverted();
  }

  // Set our (possibly massaged) deep copy.
  // 设置我们的(可能是经过按摩的)深拷贝。
  try {
   bw.setPropertyValues(new MutablePropertyValues(deepCopy));
  }
  catch (BeansException ex) {
   throw new BeanCreationException(
     mbd.getResourceDescription(), beanName, "Error setting property values", ex);
  }
 }
调用初始化方法

初始化方法的调用逻辑在initializeBean(beanName, exposedObject, mbd)里面,跟进代码查看。

一看是不是很清晰,所以以后再遇到问你啥啥啥方法先执行,直接叼面试官。

/**
  *
  * initializeBean()方法依次调用四个方法
  * 1.invokeAwareMethods()
  * 2.applyBeanPostProcessorsBeforeInitialization()
  * 3.invokeInitMethods()
  * 4.applyBeanPostProcessorsAfterInitialization()
  *
  */
 protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
  if (System.getSecurityManager() != null) {
   AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    invokeAwareMethods(beanName, bean);
    return null;
   }, getAccessControlContext());
  }
  else {
   // 1.先调用实现 aware 接口的方法
   invokeAwareMethods(beanName, bean);
  }

  Object wrappedBean = bean;
  if (mbd == null || !mbd.isSynthetic()) {
   // 2.调用 BeanPostProcessor#postProcessBeforeInitialization()方法
   wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  }

  try {
   // 3.调用初始化方法,例如实现了 InitializingBean#afterPropertiesSet() 方法
   invokeInitMethods(beanName, wrappedBean, mbd);
  }
  catch (Throwable ex) {
   throw new BeanCreationException(
     (mbd != null ? mbd.getResourceDescription() : null),
     beanName, "Invocation of init method failed", ex);
  }
  if (mbd == null || !mbd.isSynthetic()) {
   // 4.最后调用 BeanPostProcessor#postProcessAfterInitialization()
   wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  }

  return wrappedBean;
 }
循环依赖检查

这一步主要是实现一个兜底的检测,避免出现注入了一个本该被代理的但是却注入了一个原生bean的情况,这部分会在循环依赖的文章里结合来分析。

先看下代码。

if (earlySingletonExposure) {
   Object earlySingletonReference = getSingleton(beanName, false);
   //earlySingletonReference只有在检测到循环依赖的情况下才不为空
   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还没有被完全创建好
      * 也就是说还存在循环依赖
      */
     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.");
     }
    }
   }
  }
注册 DisposableBean

这也是一个回调的操作,注册一些销毁的方法。Spring 中不但提供了对于初始化方法的扩展人口 , 同样也提供了销毁方法的扩展入口,对 于销毁方法的扩展,除了我们熟知的配置属性 destroy-method 方法外,用户还可以注册后处理器 DestructionAwareBeanPostProcessor 来统一处理 bean 的销毁方法,跟进代码registerDisposableBeanIfNecessary()

/**
  * Add the given bean to the list of disposable beans in this factory,
  * registering its DisposableBean interface and/or the given destroy method
  * to be called on factory shutdown (if applicable). Only applies to singletons.
  *
  * 将给定的 bean 添加到该工厂的一次性 bean 列表中,
  * 注册其 DisposableBean 接口和或在工厂关闭时调用的给定销毁方法(如果适用)。仅适用于单例。
  *
  * @param beanName the name of the bean
  * @param bean the bean instance
  * @param mbd the bean definition for the bean
  * @see RootBeanDefinition#isSingleton
  * @see RootBeanDefinition#getDependsOn
  * @see #registerDisposableBean
  * @see #registerDependentBean
  */
 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 实现:DestructionAwareBeanPostProcessors、DisposableBean 接口、自定义销毁方法。
    /**
     * 单例模式下需要销毁的bean,此方法中会处理实现DisposableBean的bean
     * 并且对所有的bean使用DestructionAwareBeanPostProcessors处理
     * DisposableBean DestructionAwareBeanPostProcessors
     */
    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));
   }
  }
 }

总结

本文主要分析了doCreateBean()方法,但是讲得比较粗糙。回忆一下本文的思路,首先是通过类名反射得到一个class对象,然后推断构造函数去实例化得到一个bean对象,当然这部分没有深入细节去说,分多了一篇文章。然后通过byNamebyType两种方式去获取依赖注入,之后通过反射将属性注入到对象中。除去一些边边角角的校验,总的思路就是这样,还是相对清晰的,就是细节比较多。

这里牵扯的东西比较多,也算是Ioc里面比较难啃的部分了。我回看一遍我写的文章,觉得整体言不达意,脑子里想十分,说出来可能只有六分,写出来的就剩三分了。

个人水平有限,如有错误,还请指出。

如果有人看到这里,那在这里老话重提。与君共勉,路漫漫其修远兮,吾将上下而求索。

作者:幻想症患者 链接: https://www.cnblogs.com/codegitz/p/16314523.html

0a0496a4d722bc2abe239b99c26a6fe2.gif

1.Mysql完结汇总篇(18W字送给大家),完结撒花

2.如何啃下JVM这座大山,完结撒花(完结篇)

3.最全的八股文线程池总结(臭不要脸)

4.手把手教新人调优

5.上班摸鱼学习法

6.阻塞队列yyds

7.线程与

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值