全面开战系列之Spring源码---Bean实例化流程(四)


系列文章目录

前言

本篇主要分析bean实例化的大体过程,主要分为缓存,构造函数实例化bean,属性装配,回调生命周期接口这4个模块。对于各个模块的具体细节实现,在之后的章节会详细分析。本篇先把各个流程串起来,然后各个击破!


一、FactoryBean

spring提供了FactoryBean接口实现自定义实例化bean功能。来看看FactoryBean接口

public interface FactoryBean<T> {
   @Nullable
   T getObject() throws Exception;

   @Nullable
   Class<?> getObjectType();

   default boolean isSingleton() {
      return true;
   }

}

重写getObject()方法即可自定义 生成bean。

如何获取FactoryBean本身实现类?

ApplicationContext.getBean(name); 其中这个 name 必须以 "&"开头,如 &student(之后看源码就知道)。

如何获取由FactoryBean的getObject()方法生成的bean?  

ApplicationContext.getBean(name); 其中这个name 就是实现类的类名,无需特殊处理

接下来分析源码

在之前的文章,有分析到AbstractApplicationContext中的 refresh(),这个方法包含了IOC的整个启动过程。其中,有一个 finishBeanFactoryInitialization(),这个方法负责bean实例化过程。

AbstractApplicationContext.finishBeanFactoryInitialization()

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // Initialize conversion service for this context.
   //这种类型的bean最实用的场景就是用来将前端传过来的参数和后端的controller方法上的参数格式转换的时候使用
   // 如 String 转 Date
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }

   // Register a default embedded value resolver if no bean post-processor
   // (such as a PropertyPlaceholderConfigurer bean) registered any before:
   // at this point, primarily for resolution in annotation attribute values.
   //利用EmbeddedValueResolver可以很方便的实现读取配置文件的属性:${}
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   //先初始化 LoadTimeWeaverAware 类型的 Bean
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }

   // Stop using the temporary ClassLoader for type matching.
   //停止使用用于类型匹配的临时类加载器
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   //冻结所有的bean定义,即已注册的bean定义将不会被修改或后处理
   beanFactory.freezeConfiguration();

   // Instantiate all remaining (non-lazy-init) singletons.
   //初始化
   beanFactory.preInstantiateSingletons();
}


关注最后一行代码,beanFactory.preInstantiateSingletons(); 即DefaultListableBeanFactory.preInstantiateSingletons()

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.
   // this.beanDefinitionNames 保存了所有的 beanNames
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...,遍历BeanName,实例化
   for (String beanName : beanNames) {
      // 该方法的merge是指如果bean类继承有父类,那么就将它所有的父类的bd融合成一个RootBeanDefinition返回
      // 合并父 Bean 中的配置,主要是 <bean id="" class="" parent="" /> 中的 parent属性
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      //非抽象类,单例,非懒加载
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {//如果是factoryBean,则需要加& 才能使用getBean
            //在 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 {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean<?>) factory).isEagerInit());
               }
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
         else {  // 不是FactoryBean的直接使用此方法进行初始化
            getBean(beanName);
         }
      }
   }

   // Trigger post-initialization callback for all applicable beans...
   // 如果bean实现了 SmartInitializingSingleton 接口的,那么在这里得到回调
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      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();
         }
      }
   }
}

在遍历  beanNames 中,先判断 beanName是否是 FactoryBean类型,如果是,则实例化,通过这个方法:getBean(FACTORY_BEAN_PREFIX + beanName); 容器会自动为beanName加上特殊前缀:&,由此可见,对于容器中的FactoryBean类型的bean定义,IOC容器默认返回 FactoryBean的 getObject()中的实例。

具体看一下AbstractBeanFactory.isFactoryBean() ,这个方法通过 beanName 获取对应的bean定义 class类型,判断class是否是FactoryBean.class

public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
   //转化名称,如"&name" --> "name"。因为容器中的beanName不会以"&"开头
   String beanName = transformedBeanName(name);
   //先从缓存中获取实例
   Object beanInstance = getSingleton(beanName, false);
   if (beanInstance != null) {
      return (beanInstance instanceof FactoryBean);
   }
   // No singleton instance found -> check bean definition.
   //从父容器中获取bean定义
   if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
      // No bean definition found in this factory -> delegate to parent.
      return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
   }
   //从当前容器中获取bean定义,定义中的class 与FactoryBean.class进行对比
   return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
   Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
   return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
}

接下来具体看一下如何实例化bean的,即AbstractBeanFactory.getBean()方法

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

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
   /*
    * 通过 name 获取 beanName。这里不使用 name 直接作为 beanName 有两点原因:
    * 1. name 可能会以 & 字符开头,表明调用者想获取 FactoryBean 本身,而非 FactoryBean
    *    实现类所创建的 bean。在 BeanFactory 中,FactoryBean 的实现类和其他的 bean 存储
    *    方式是一致的,即 <beanName, bean>,beanName 中是没有 & 这个字符的。所以我们需要
    *    将 name 的首字符 & 移除,这样才能从缓存里取到 FactoryBean 实例。
    * 2. 若 name 是一个别名,则应将别名转换为具体的实例名,也就是 beanName。
    */
   // 获取beanName,处理两种情况,一个是前面说的 FactoryBean(前面带 ‘&’),再一个这个方法是可以根据别名来获取Bean的,所以在这里是要转换成最正统的BeanName
   //主要逻辑就是如果是FactoryBean就把&去掉,如果是别名就把根据别名获取真实名称
   final String beanName = transformedBeanName(name);
   Object bean;

   // Eagerly check singleton cache for manually registered singletons.
   // 检查是否已初始化,从缓存中获取实例
   Object sharedInstance = getSingleton(beanName);
   if (sharedInstance != null && args == null) {
      //如果已经初始化过了,且没有传args参数就代表是get,直接取出返回
      if (logger.isTraceEnabled()) {
         if (isSingletonCurrentlyInCreation(beanName)) {
            logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                  "' that is not fully initialized yet - a consequence of a circular reference");
         }
         else {
            logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
         }
      }
      /*
       * 如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。但如果
       * sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的
       * bean 实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回
       * 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。
       */
      // 这里如果是普通Bean 的话,直接返回,如果是 FactoryBean 的话,返回它创建的那个实例对象
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }
   /*
    * 如果上面的条件不满足,则表明 sharedInstance 可能为空,此时 beanName 对应的 bean
    * 实例可能还未创建。这里还存在另一种可能,如果当前容器有父容器,beanName 对应的 bean 实例
    * 可能是在父容器中被创建了,所以在创建实例前,需要先去父容器里检查一下。
    */
   else {
      // Fail if we're already creating this bean instance:
      // We're assumably within a circular reference.
      // 如果存在prototype类型的这个bean, Spring无法处理循环依赖对象是prototype类型的问题。
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }

      // Check if bean definition exists in this factory.
      //先从父容器取bean,如果不存在则创建。这里实现springMvc和spring容器交互
      //springMvc容器可以访问父容器,Spring容器不能访问子容器
      BeanFactory parentBeanFactory = getParentBeanFactory();
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
         // 如果当前BeanDefinition不存在这个bean且具有父BeanFactory
         // 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);
         }
      }
      //将beanName标记到baen工厂的alreadyCreated的Set中,保证不会重复创建该bean
      if (!typeCheckOnly) {
         markBeanAsCreated(beanName);
      }
      //准备创建bean
      try {
         // 合并父 BeanDefinition 与子 BeanDefinition
         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         checkMergedBeanDefinition(mbd, beanName, args);

         // Guarantee initialization of beans that the current bean depends on.
         // 先初始化依赖的所有 Bean, depends-on 中定义的依赖
         String[] dependsOn = mbd.getDependsOn();
         if (dependsOn != null) {
            for (String dep : dependsOn) {
               /*
                * 检测是否存在 depends-on 循环依赖,若存在则抛异常。比如 A 依赖 B,
                * B 又依赖 A,他们的配置如下:
                *   <bean id="beanA" class="BeanA" depends-on="beanB">
                *   <bean id="beanB" class="BeanB" depends-on="beanA">
                *
                * beanA 要求 beanB 在其之前被创建,但 beanB 又要求 beanA 先于它
                * 创建。这个时候形成了循环,对于 depends-on 循环,Spring 会直接
                * 抛出异常
                */
               if (isDependent(beanName, dep)) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
               }
               // 注册一下依赖关系
               registerDependentBean(dep, beanName);
               try {
                  // 先初始化被依赖项
                  getBean(dep);
               }
               catch (NoSuchBeanDefinitionException ex) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
               }
            }
         }

         // Create bean instance.,单例
         if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  //执行创建 Bean,但没有设置属性,创建 bean 实例,createBean 返回的 bean 是完全实例化好的
                  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.
                  destroySingleton(beanName);
                  throw ex;
               }
            });
            // 如果 bean 是 FactoryBean 类型,则调用工厂方法获取真正的 bean 实例。否则直接返回 bean 实例
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }
         // 如果是prototype,不会缓存
         else if (mbd.isPrototype()) {
            // It's a prototype -> create a new instance.
            Object prototypeInstance = null;
            try {
               beforePrototypeCreation(beanName);
               // 执行创建 Bean
               prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
               afterPrototypeCreation(beanName);
            }
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }
         // 如果不是 singleton 和 prototype 那么就是自定义的scope、例如Web项目中的session等类型,这里就交给自定义scope的应用方去实现
         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) {
               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);
            }
         }
      }
      catch (BeansException ex) {
         cleanupAfterBeanCreationFailure(beanName);
         throw ex;
      }
   }
   //检查bean的类型
   // Check if required type matches the type of the actual bean instance.
   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());
      }
   }
   return (T) bean;
}

doGetBean()方法很长这里面是具体实例化过程,

主要分为以下步骤:

1. 从缓存中获取bean,如果有直接返回,没有则开始实例化,缓存逻辑主要在 getSingleton(beanName)这里面

2. 做一些校验,整合。如 对于prototype(多例)类型的bean无法实现循环依赖,整合父容器中的bean等

3.先实例化depends-on 类型的bean,如 <bean id="beanA" class="BeanA" depends-on="beanB">

4.实例化各种作用域的bean

实例化结束后,对于FactoryBean接口来说,需要关注 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); 此时,sharedInstance 已经是具体的实例了 

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.
   if (BeanFactoryUtils.isFactoryDereference(name)) {
      if (beanInstance instanceof NullBean) {
         return beanInstance;
      }
      //以&开头的beanName,表明beanInstance一定是想要 FactoryBean类型,否则抛异常
      if (!(beanInstance instanceof FactoryBean)) {
         throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
      }
   }

   // 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.
   //获取FactoryBean本身,如: applicationContext.getBean("factory"),name不以&开头表明想要获取该类本身,否则获取该类的getObject方法返回的bean
   if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
      return beanInstance;
   }
   //调用 FactoryBean 接口的 getObject方法创建bean ,然后返回
   Object object = null;
   if (mbd == null) {
      /*
       * 如果 mbd 为空,则从缓存中加载 bean。FactoryBean 生成的单例 bean 会被缓存
       * 在 factoryBeanObjectCache 集合中,不用每次都创建
       */
      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.
      if (mbd == null && containsBeanDefinition(beanName)) {
         mbd = getMergedLocalBeanDefinition(beanName);
      }
      boolean synthetic = (mbd != null && mbd.isSynthetic());
      //创建 bean
      object = getObjectFromFactoryBean(factory, beanName, !synthetic);
   }
   return object;
}

 在getObjectForBeanInstance中,主要逻辑为:判断beanName是否意&开头,如果不是,则直接返回beanInstance,如果是,则最终调用FactoryBeanRegistrySupport.getObjectFromFactoryBean(factory, beanName, !synthetic)来创建bean。即最终调用 FactoryBean.getObject(); 方法创建自定义bean 然后返回。

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
   /*
    * FactoryBean 也有单例和非单例之分,针对不同类型的 FactoryBean,这里有两种处理方式:
    *   1. 单例 FactoryBean 生成的 bean 实例也认为是单例类型。需放入缓存中,供后续重复使用
    *   2. 非单例 FactoryBean 生成的 bean 实例则不会被放入缓存中,每次都会创建新的实例
    */
   if (factory.isSingleton() && containsSingleton(beanName)) {
      synchronized (getSingletonMutex()) {
         Object object = this.factoryBeanObjectCache.get(beanName);
         if (object == null) {
            //这里调用 FactoryBean.getObject()
            object = doGetObjectFromFactoryBean(factory, beanName);
            // Only post-process and store if not put there already during getObject() call above
            // (e.g. because of circular reference processing triggered by custom getBean calls)
            Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
            if (alreadyThere != null) {
               object = alreadyThere;
            }
            else {
               if (shouldPostProcess) {
                  // shouldPostProcess 等价于上一个方法中的 !synthetic,用于表示是否应用后置处理
                  if (isSingletonCurrentlyInCreation(beanName)) {
                     // Temporarily return non-post-processed object, not storing it yet..
                     return object;
                  }
                  //加入singletonsCurrentlyInCreation 中(保存当前正在创建的类)
                  beforeSingletonCreation(beanName);
                  try {
                     object = postProcessObjectFromFactoryBean(object, beanName);
                  }
                  catch (Throwable ex) {
                     throw new BeanCreationException(beanName,
                           "Post-processing of FactoryBean's singleton object failed", ex);
                  }
                  finally {
                     //移除singletonsCurrentlyInCreation中的beanName
                     afterSingletonCreation(beanName);
                  }
               }
               if (containsSingleton(beanName)) {//放入缓存
                  this.factoryBeanObjectCache.put(beanName, object);
               }
            }
         }
         return object;
      }
   }
   else {
      Object object = doGetObjectFromFactoryBean(factory, beanName);
      if (shouldPostProcess) {
         try {
            object = postProcessObjectFromFactoryBean(object, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
         }
      }
      return object;
   }
}
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
      throws BeanCreationException {

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

   // Do not accept a null value for a FactoryBean that's not fully
   // initialized yet: Many FactoryBeans just return null then.
   if (object == null) {
      if (isSingletonCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(
               beanName, "FactoryBean which is currently in creation returned null from getObject");
      }
      object = new NullBean();
   }
   return object;
}

二、实例化Bean过程

在前面分析FactoryBean接口过程中,有提到实例化bean过程

doGetBean()方法具体实例化过程,

主要分为以下步骤:

1. 从缓存中获取bean,如果有直接返回,没有则开始实例化,缓存逻辑主要在 getSingleton(beanName)这里面

2. 做一些校验,整合。如 对于prototype(多例)类型的bean无法实现循环依赖,整合父容器中的bean等

3.先实例化depends-on 类型的bean,如 <bean id="beanA" class="BeanA" depends-on="beanB">

4.实例化各种作用域的bean

这里主要分析一下缓存,和 各作用域实例化过程。


2.1缓存

在AbstractBeanFactory 类中的 doGetBean()方法,这个方法流程中有调用到DefaultSingletonBeanRegistry.getSingleton(beanName),这里面就是spring的缓存。

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

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   // 从 singletonObjects 获取实例,singletonObjects 中缓存的实例都是完全实例化好的 bean,可以直接使用
   Object singletonObject = this.singletonObjects.get(beanName);
   //检查当前bean是否正在被当前线程创建
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      /*
       * 如果 singletonObject = null,表明还没创建,或者还没完全创建好。
       * 这里判断 beanName 对应的 bean 是否正在创建中
       */
      synchronized (this.singletonObjects) {
         // 从 earlySingletonObjects 中获取提前曝光的 bean,用于处理循环引用
         singletonObject = this.earlySingletonObjects.get(beanName);
         // 如果如果 singletonObject = null,且允许提前曝光 bean 实例,则从相应的 ObjectFactory 获取一个原始的(raw)bean(尚未填充属性)
         if (singletonObject == null && allowEarlyReference) {
            // 获取相应的工厂类
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {//表明
               // 提前曝光 bean 实例,用于解决循环依赖
               singletonObject = singletonFactory.getObject();
               // 放入缓存中,如果还有其他 bean 依赖当前 bean,其他 bean 可以直接从 earlySingletonObjects 取结果
               this.earlySingletonObjects.put(beanName, singletonObject);
               //放入earlySingletonObjects中,singletonFactories就可以清除,节约内存
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}


这里面的缓存结构涉及3个变量

/** Cache of singleton objects: bean name to bean instance. 完全初始化好的bean*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** Cache of singleton factories: bean name to ObjectFactory.用于存放 bean 工厂。bean 工厂所产生的 bean 是还未完成初始化的 bean。 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/** Cache of early singleton objects: bean name to bean instance. 用于存放还在初始化中的 bean,用于解决循环依赖*/
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

称为3级缓存,用于解决循环依赖问题。关于循环依赖,后续章节再详细分析,这里主要关注缓存获取流程即可。其实spring很多地方都有用到缓存,这样可以加快程序运行速度,以后写代码也可以仿造(get到小技巧)

2.2实例化bean

bean的作用域分为: singleton,prototype,request,session,application,websocket

这里只分析singleton(单例),即每个 Spring IoC 容器中只允许存在一个对象实例(同一个beanName)

关注AbstractBeanFactory的doCreateBean方法中一段代码

// Create bean instance.,单例
if (mbd.isSingleton()) {
   sharedInstance = getSingleton(beanName, () -> {
      try {
         //执行创建 Bean,createBean 返回的 bean 是完全实例化好的
         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.
         destroySingleton(beanName);
         throw ex;
      }
   });
   // 如果 bean 是 FactoryBean 类型,则调用工厂方法获取真正的 bean 实例。否则直接返回 bean 实例
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

在 DefaultSingletonBeanRegistry.getSingleton()方法里面进行实例化操作,这里面的主要逻辑如下:

1. 调用传入的lambda方法。实际上就是调用createBean(beanName, mbd, args); 

2.操作缓存

先来看一下DefaultSingletonBeanRegistry.getSingleton()整体流程

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) {
            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 + "'");
         }
         // 将正在创建的bean加入到Set<String> singletonsCurrentlyInCreation中
         beforeSingletonCreation(beanName);
         boolean newSingleton = false;
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }
         try { // 调用传入的lambda方法。实际上就是调用createBean(beanName, mbd, args);
            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;
            }
            // 将正在创建的bean从Set<String> singletonsCurrentlyInCreation中移除
            afterSingletonCreation(beanName);
         }
         if (newSingleton) {
            // 添加到bean工厂的singletonObjects中。加入缓存,此时bean的属性完整了
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}
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);
   }
}

其中, addSingleton 和缓存有关,这里是解决循环依赖的关键

我们这节先重点分析 传入的 ObjectFactory 接口的 getObject 方法,即 AbstractAutowireCapableBeanFactory.createBean()。这个真正方法实现bean实例化操作

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.
   // 确保 BeanDefinition 中的 Class 被加载
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // Prepare method overrides.
   // 准备方法覆写,如果bean中定义了 <lookup-method /> 和 <replaced-method />
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
      // 如果有代理(自定义bean)的话直接返回,处理InstantiationAwareBeanPostProcessor接口回调
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {//返回不为空,表明自定义bean实现成功,直接返回
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   try {
      //实例化bean
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
         logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      // A previously detected exception with proper bean creation context already,
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   }
}

这里直接关注  Object beanInstance = doCreateBean(beanName, mbdToUse, args);这个方法,里面的大体逻辑为:

1.创建bean实例,主要通过 createBeanInstance(beanName, mbd, args) 这个方法

2.处理MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法

3.是否加入缓存

4.属性装配

5.各种接口,方法的回调,即网上常说的生命周期。

先看一眼 AbstractAutowireCapableBeanFactory.doCreateBean()方法的全貌

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

   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      // 从缓存中获取 BeanWrapper,并清理相关记录
      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.
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         try {
            // 循环调用实现了MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法
            // Spring对这个接口有几个默认的实现,其中大家最熟悉的一个是操作@Autowired注解的
            //CommonAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor, ApplicationListenerDetector会被回调postProcessMergedBeanDefinition方法执行各自的逻辑。
            // CommonAnnotationBeanPostProcessor处理@PostConstruct 和 @PreDestroy方法添加到org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#lifecycleMetadataCache CurrentHashMap中。
            // 并且如果有就分别注册到bd的externallyManagedInitMethods和externallyManagedDestroyMethods Set集合中。
            // org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition是再次进行bd的融合。
            // 通过clazz.getDeclaredFields()得到bean中所有的属性字段和方法。然后挨个对其进行解析转换成metadata,最终放入到AutowiredAnnotationBeanPostProcessor#injectionMetadataCache中。
            // ApplicationListenerDetector很简单,将beanName和是否是singleton的boolean变量放到ApplicationListenerDetector对象的Map<String, Boolean> singletonNames中。
            //解析注解上的属性,还未完成注入操作
            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.
   /*
    * earlySingletonExposure 是一个重要的变量,这里要说明一下。该变量用于表示是否提前暴露
    * 单例 bean,用于解决循环依赖。earlySingletonExposure 由三个条件综合而成,如下:
    *   条件1:mbd.isSingleton() - 表示 bean 是否是单例类型
    *   条件2:allowCircularReferences - 是否允许循环依赖
    *   条件3:isSingletonCurrentlyInCreation(beanName) - 当前 bean 是否处于创建的状态中
    *
    * earlySingletonExposure = 条件1 && 条件2 && 条件3
    *                        = 单例 && 是否允许循环依赖 && 是否存于创建状态中。
    */
   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");
      }
      //当正在创建A时,A依赖B,此时通过(将A作为ObjectFactory放入单例工厂中进行early expose,此处B需要引用A,但A正在创建,从单例工厂拿到ObjectFactory,从而允许循环依赖
      // 获取早期 bean 的引用,如果 bean 中的方法被 AOP 切点所匹配到,此时 AOP 相关逻辑会介入
      //在 getSingleton中会应用到ObjectFactory.getObject()获取早期bean引用,bean还没有完整的属性
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      //负责属性装配,很重要(依赖注入)
      populateBean(beanName, mbd, instanceWrapper);
      //这里是处理bean初始化完成后的各种回调,例如init-method、InitializingBean 接口、BeanPostProcessor 接口
      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);
      if (earlySingletonReference != null) {
         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);
               }
            }
            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 {
      // 把bean注册到相应的Scope中
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
   }

   return exposedObject;
}

关注 instanceWrapper = createBeanInstance(beanName, mbd, args); 这里面根据配置生成bean,如 静态工厂方法,实例化工厂,构造函数

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // Make sure bean class is actually resolved at this point.
   //确保已经加载了class, 1.1 确保此时beanClassName已经加载,当然注解驱动时不会设置beanClassName属性
   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());
   }
   // 2. Supplier创建对象,Spring 新推出的 bean 创建方式。
   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
   }
   // 旧版本的Spring可以通过xml配置 <bean id='A' class='xxx' factory-method='getA'>从而获得静态的工厂方法获得bean A
   //3. 工厂方法实例化,包括实例化工厂和静态工厂
   if (mbd.getFactoryMethodName() != null) { // 采用工厂方法实例化
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }
   // 缓存标志位
   // RootBeanDefinition.resolvedConstructorOrFactoryMethod专门用来缓存构造函数,
   // constructorArgumentsResolved用来存放构造是有参还是无参。
   // 有参走autowireConstructor,无参走instantiateBean
   // Shortcut when re-creating the same bean...
   boolean resolved = false;
   //是否采用有参构造函数注入
   boolean autowireNecessary = false;
   if (args == null) { //4.1 args: 外部化参数,只能当无外部参数时才使用缓存。不推荐使用外部化参数,因为外部化参数会覆盖配置参数 bd.args
      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?
   //  5.1 是否指定了构造器,
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
   // 指定注入模式为构造器自动注入模式,<bean id="beanA" class="com.binarylei.spring.ioc.BeanA" autowire="constructor"/>
   /*
    * 下面的条件分支条件用于判断使用什么方式构造 bean 实例,有两种方式可选 - 构造方法自动
    * 注入和默认构造方法。判断的条件由4部分综合而成,如下:
    *
    *    条件1:ctors != null -> 后置处理器返回构造方法数组是否为空
    *
    *    条件2:mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR
    *              -> bean 配置中的 autowire 属性是否为 constructor
    *    条件3:mbd.hasConstructorArgumentValues()
    *              -> constructorArgumentValues 是否存在元素,即 bean 配置文件中
    *                 是否配置了 <construct-arg/>
    *    条件4:!ObjectUtils.isEmpty(args)
    *              -> args 数组是否存在元素,args 是由用户调用
    *                 getBean(String name, Object... args) 传入的
    *
    * 上面4个条件,只要有一个为 true,就会通过构造方法自动注入的方式构造 bean 实例
    */
   //@Bean也走这里 默认注入类型:AUTOWIRE_CONSTRUCTOR
   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      //指定参数。包括配置参数 bd.constructorArgumentValues 或外部参数 args。
      //  5.2 构造器实例化
      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.,默认构造函数实例化bean,使用无参构造
   return instantiateBean(beanName, mbd);
}

对于通过构造函数进行实例化的bean,最终是通过反射方法生成bean。但是,由于一个bean可能存在多个构造函数,对于选择有参构造函数进行实例化的bean,spring需要判断选择合适的构造函数。

这里面的逻辑有些复杂,autowireConstructor(beanName, mbd, ctors, args),这个方法里面包含了spring选择构造函数的逻辑,有兴趣的自行深入了解吧。

在这直接分析无参构造函数实例化过程,AbstractAutowireCapableBeanFactory.instantiateBean(beanName, mbd); 

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
   try {
      Object beanInstance;
      final BeanFactory parent = this;
      if (System.getSecurityManager() != null) {
         beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
               getInstantiationStrategy().instantiate(mbd, beanName, parent),
               getAccessControlContext());
      }
      else {
         //实例化
         beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
      }//封装成wrapper
      BeanWrapper bw = new BeanWrapperImpl(beanInstance);
      initBeanWrapper(bw);
      return bw;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
   }
}
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
   // Don't override the class with CGLIB if no overrides.
   // 如果不存在方法覆写,那就使用 java 反射进行实例化,否则使用 CGLIB,
   if (!bd.hasMethodOverrides()) {
      Constructor<?> constructorToUse;
      synchronized (bd.constructorArgumentLock) {
         constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
         if (constructorToUse == null) {
            final Class<?> clazz = bd.getBeanClass();
            if (clazz.isInterface()) {
               throw new BeanInstantiationException(clazz, "Specified class is an interface");
            }
            try {
               if (System.getSecurityManager() != null) {
                  constructorToUse = AccessController.doPrivileged(
                        (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
               }
               else {
                  //获取默认的构造函数
                  constructorToUse = clazz.getDeclaredConstructor();
               }
               //设置到bd缓存上
               bd.resolvedConstructorOrFactoryMethod = constructorToUse;
            }
            catch (Throwable ex) {
               throw new BeanInstantiationException(clazz, "No default constructor found", ex);
            }
         }
      }
      //执行实例化
      return BeanUtils.instantiateClass(constructorToUse);
   }
   else {
      // Must generate CGLIB subclass.
      return instantiateWithMethodInjection(bd, beanName, owner);
   }
}

在SimpleInstantiationStrategy.instantiate()方法最终会调用到 BeanUtils.instantiateClass(), 通过  Constructor.newInstance(args) 创建bean,对于无参构造函数创建的bean,此时bean的属性都为空,所以接下去需要进行属性装配(依赖注入)。

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
   Assert.notNull(ctor, "Constructor must not be null");
   try {
      ReflectionUtils.makeAccessible(ctor);
      return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
            KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
   }
   catch (InstantiationException ex) {
      throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
   }
   catch (IllegalAccessException ex) {
      throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
   }
   catch (IllegalArgumentException ex) {
      throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
   }
   catch (InvocationTargetException ex) {
      throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
   }
}

2.3属性装配

属性装配也可包含依赖注入

Spring的依赖注入 分为基于构造函数注入,基于setter方法注入,自动装配。

其中,自动装配方式又分为:no,byName,byType,constructor. 

属性装配的源码在  AbstractAutowireCapableBeanFactory. populateBean()中,这里面的大体逻辑为:

1.处理 byName,byType类型的自动装配

2.处理InstantiationAwareBeanPostProcessor接口的回调方法,如 @Autowired、@Value 注解的属性进行设值

3.对属性进行赋值,如通过xml配置属性(通过set方法进行反射赋值)

具体看一下这个方法

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.
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            // 如果返回 false,代表不需要进行后续的属性设值,也不需要再经过其他的 BeanPostProcessor 的处理
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               /*
                * 如果上面设置 continueWithPropertyPopulation = false,表明用户可能已经自己填充了
                * bean 的属性,不需要 Spring 帮忙填充了。此时直接返回即可
                */
               return;
            }
         }
      }
   }

   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      //深度拷贝一份现有属性
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // Add property values based on autowire by name if applicable.
      // 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系
      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 = newPvs;
   }

   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

   PropertyDescriptor[] filteredPds = null;
   if (hasInstAwareBpps) {
      if (pvs == null) {
         //这个变量主要用来保存非注解方式注入的属性,如XML配置,后面判断该变量是否为空,
         //然后对该变量进行反射注入操作
         pvs = mbd.getPropertyValues();
      }
      /*
       * 这里又是一种后置处理,用于在 Spring 填充属性到 bean 对象前,对属性的值进行相应的处理,
       * 比如可以修改某些属性的值。这时注入到 bean 中的值就不是配置文件中的内容了,
       * 而是经过后置处理器修改后的内容
       */
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            //这里会对所有标记@Autowired、@Value 注解的属性进行设值
            //如果还有其他方式的属性配置,如xml,会在后续继续进行复制操作。pvs传入什么,pvsToUser就输出什么
            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);
      }
      checkDependencies(beanName, mbd, filteredPds, pvs);
   }

   if (pvs != null) {
      //一个类如果只通过注解方式进行依赖注入,那么pvs的长度为0,在ibp.postProcessProperties
      // 已经完成了依赖注入
      // 设置 bean 实例的属性值,主要是通过xml配置方式
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

属性装配整体流程都在上面的方法中,这里不打算展开,因为要展开详细有点多,准备放在下一章单独分析,这里先了解流程。

2.4回调接口

bean到这里基本成型,属性也完整了,spring考虑到灵活性,扩展性,开发了一系列的接口供开发者使用。包括Aware, InitializingBean,  BeanPostProcessor 接口,init-Method 方法

接下来看源码,AbstractAutowireCapableBeanFactory.initializeBean(beanName, exposedObject, mbd) 方法

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 {
      //处理 各种Aware接口,如BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
      invokeAwareMethods(beanName, bean);
   }

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

   try {
      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()) {//调用BeanPostProcessor.postProcessAfterInitialization方法
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}



总结

这篇文章主要是梳理了spring 实例化bean的流程,而并没有深入去分析各个细节模块。在下一章准备深入分析一下属性装配这一模块,一起期待吧!

写到这里,我只想说这篇文章是我写过的跨度最长时间文章。这篇文章至少在我的草稿箱里面呆了2个月。曾经几度想提起比来,但都未能如愿。原因嘛,主要是懒,当然还有其他原因。我也时常告诫自己,与其每天刷新闻,逛b站,不如把时间花在学习上面?思想惰性根深蒂固,习惯了舒适区的我已经成废人了。对此,我深感愧疚,同时对这种行为进行了严厉的自我谴责!还在最后幡然醒悟,痛改前非,赶在2021年前勉强完成,给2020画上了一个句号,惭愧惭愧。

最近有些丧,来句结语吧,大家不要受我影响~~

水纹珍簟思悠悠,千里佳期一夕休。

从此无心爱良夜,任他明月下西楼。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值