02.spring全家桶之深入getBean()和循环依赖

本文以一个spring项目为例深入getBean()底层

java 复制代码
ctx.getBean()执行流程总结如下:
1.  拿到beanName:factoryBean以&开头,需要去掉;通过别名拿到真实beanName
        String beanName = transformedBeanName(name);
2.  先从缓存中拿
        从一级缓存singletonObjects中拿:
            Object singletonObject = this.singletonObjects.get(beanName);如果有就直接返回
        如果一级缓存singletonObjects中没有,判断当前对象是否正在创建
            if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
                //如果对象正在被创建
                //从二级缓存中拿
                singletonObject = this.earlySingletonObjects.get(beanName);
            }
3.1.  bean实例化之前的后置处理器=====================================> postProcessBeforeInstantiation
           protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
              //获取容器中的所有bean后置处理器
              for (BeanPostProcessor bp : getBeanPostProcessors()) {
                 if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    /**
                     * 【很重要】
                     * 我们AOP @EnableAspectJAutoProxy 为我们容器中导入了 AnnotationAwareAspectJAutoProxyCreator
                     *   ===> 当我们使用@EnableAspectJAutoProxy后,注册beanDefinition:AnnotationAwareAspectJAutoProxyCreator
                     *          它实现了BeanPostProcessor和InstantiationAwareBeanPostProcessor接口

                     * 我们事务注解@EnableTransactionManagement 为我们的容器导入了 InfrastructureAdvisorAutoProxyCreator
                     * 都是实现了我们的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
                     * 进行后置处理解析切面
                     */
                    Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                    if (result != null) {
                       return result;
                    }
                 }
              }
              return null;
           }
4.2,  bean初始化之后的后置处理器=====================================> postProcessAfterInitialization
           public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
              Object result = existingBean;
              //获取我们容器中的所有的bean的后置处理器
              for (BeanPostProcessor processor : getBeanPostProcessors()) {
                 /**
                  * 在这里是后置处理器的【第九次调用】 aop和事务都会在这里生存代理对象
                  *
                  * 【很重要】
                  * 我们AOP @EnableAspectJAutoProxy 为我们容器中导入了 AnnotationAwareAspectJAutoProxyCreator
                  * 我们事务注解@EnableTransactionManagement 为我们的容器导入了 InfrastructureAdvisorAutoProxyCreator
                  * 都是实现了我们的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
                  * 在这里实现的是BeanPostProcessor接口的postProcessAfterInitialization来生成我们的代理对象
                  */
                 Object current = processor.postProcessAfterInitialization(result, beanName);
                 //若只有有一个返回null 那么直接返回原始的
                 if (current == null) {
                    return result;
                 }
                 result = current;
              }
              return result;
           }

5.3.   决定构造器=====================================> determineCandidateConstructors
        protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName) throws BeansException {
              //beanClass对象不为空 且 ioc容器中有InstantiationAwareBeanPostProcessors的后置处理器
              if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
                 //获取到容器中所有的后置处理器BeanPostProcessors
                 for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                       SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                          //调用我们后置处理器的determineCandidateConstructors 来决定我们的构造方法
                          Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
                          if (ctors != null) {
                          return ctors;
                       }
                    }
                 }
              }
              return null;
           }

6.4.  =====================================> 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);
                 }
              }
           }
7.5   bean实例化之后的后置处理器=====================================> postProcessAfterInstantiation
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
             //获取容器中的所有的BeanPostProcessor
             for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                   InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                   //若存在后置处理器给我们属性赋值了,那么返回false 可以来修改我们的开关变量,就不会走下面的逻辑了
                   if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                      // 返回值为是否继续填充 bean
                      // postProcessAfterInstantiation:如果应该在 bean上面设置属性则返回 true,否则返回 false
                      // 一般情况下,应该是返回true 。
                      // 返回 false 的话,将会阻止在此 Bean 实例上调用任何后续的 InstantiationAwareBeanPostProcessor 实
                      continueWithPropertyPopulation = false;
                      break;
                   }
                }
             }
          }
        }
8.6   属性赋值后置处理器=====================================> postProcessPropertyValues
            //获取所有的后置处理器
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
               if (bp instanceof InstantiationAwareBeanPostProcessor) {
                  InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                  //对依赖对象进行后置处理
                  pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                  if (pvs == null) {
                     return;
                  }
               }
            }

BeanNameAware.setBeanName
BeanClassLoaderAware.setBeanClassLoader
BeanFactoryAware.setBeanFactory


9.7   bean初始化之前的后置处理器=====================================> postProcessBeforeInitialization
       public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
          Object result = existingBean;
          //获取我们容器中的所有的bean的后置处理器
          for (BeanPostProcessor processor : getBeanPostProcessors()) {
             //挨个调用我们的bean的后置处理器的postProcessBeforeInitialization
             Object current = processor.postProcessBeforeInitialization(result, beanName);
             //若只有有一个返回null 那么直接返回原始的
             if (current == null) {
                return result;
             }
             result = current;
          }
          return result;
       }

InitializingBean.afterPropertiesSet
调用我们自己的初始化方法AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(beanName, bean, mbd);


10.8,  bean初始化之后的后置处理器=====================================> postProcessAfterInitialization
           public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
              Object result = existingBean;
              //获取我们容器中的所有的bean的后置处理器
              for (BeanPostProcessor processor : getBeanPostProcessors()) {
                 /**
                  * 在这里是后置处理器的【第九次调用】 aop和事务都会在这里生存代理对象
                  *
                  * 【很重要】
                  * 我们AOP @EnableAspectJAutoProxy 为我们容器中导入了 AnnotationAwareAspectJAutoProxyCreator
                  * 我们事务注解@EnableTransactionManagement 为我们的容器导入了 InfrastructureAdvisorAutoProxyCreator
                  * 都是实现了我们的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
                  * 在这里实现的是BeanPostProcessor接口的postProcessAfterInitialization来生成我们的代理对象
                  */
                 Object current = processor.postProcessAfterInitialization(result, beanName);
                 //若只有有一个返回null 那么直接返回原始的
                 if (current == null) {
                    return result;
                 }
                 result = current;
              }
              return result;
           }

getBean() 示例

新建一个maven项目,引入依赖:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.2.15.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.15.RELEASE</version>
    </dependency>
    
</dependencies>

测试DEMO:

java 复制代码
package com.matio.config;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;

@Configuration
public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(App.class);
        App app = context.getBean(App.class);
        System.out.println(app);
    }
}

spring ioc 加载流程图

getBean() 流程

1. transformedBeanName()

执行流程:

  1. 如果传入的beanName以&开头,就去掉&(说明想获取一个FactoryBean)
  2. 如果传入的beanName是别名,就获取真正的beanName
java 复制代码
/**
 * 解析别名
 *
 * @param name bean的名称(可能包含工厂Bean的&,或者是别名)
 * @return 真正bean的名称
 */
protected String transformedBeanName(String name) {
   //真正的解析bean的名称
   return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}


// 去除工厂Bean的前缀(&)
public static String transformedBeanName(String name) {
   Assert.notNull(name, "'name' must not be null");
   String beanName = name;
   //判断当前的beanName是不是工厂Bean  若是的话去除工厂bean的前缀(&)
   while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
      //去除工厂bean(&)的前缀
      beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
   }
   return beanName;
}

/**
 * 解析bean 的别名
 * @param name bean传入的名称
 * @return 返回的名称
 */
public String canonicalName(String name) {
   String canonicalName = name;
     /**
    * 这里使用 while 循环进行处理,原因是:可能会存在多重别名的问题,即别名指向别名。比如下面
    * 的配置:
    *   <bean id="tulingDao" class="com.tuling.mapper.tulingDao"/>
    *   <alias name="tulingDao" alias="aliasA"/>
    *   <alias name="aliasA" alias="aliasB"/>
    *
    * 上面的别名指向关系为 aliasB -> aliasA -> tulingDao,对于上面的别名配置,aliasMap 中数据
    * 视图为:aliasMap = [<aliasB, aliasA>, <aliasA, tulingDao>]。通过下面的循环解析别名
    * aliasB 最终指向的 beanName
    */
   String resolvedName;
   do {
      //获取bean的真实名称
      resolvedName = this.aliasMap.get(canonicalName);
      if (resolvedName != null) {
         //赋值给 canonicalName属性
         canonicalName = resolvedName;
      }
   }
   while (resolvedName != null);
   return canonicalName;
}

2. Object sharedInstance = getSingleton(beanName);

从spring三级缓存中获取bean,源码如下:

先尝试从缓存中获取bean,如果bean已经创建好了,那就直接返回

java 复制代码
/**
 * 在网上很多很多写源码的大佬或者是<spring源码深度解析>一书上,也没有说清楚为啥要使用三级缓存(二级缓存可不可以能够
 * 解决) 答案是:可以, 但是没有很好的扩展性为啥这么说.......
 * 原因: 获取三级缓存-----getEarlyBeanReference()经过一系列的后置处理来给我们早期对象进行特殊化处理
 * //从三级缓存中获取包装对象的时候 ,他会经过一次后置处理器的处理对我们早期对象的bean进行
 * 特殊化处理,但是spring的原生后置处理器没有经过处理,而是留给了我们程序员进行扩展
 * singletonObject = singletonFactory.getObject();
 * 把三级缓存移植到二级缓存中
 * this.earlySingletonObjects.put(beanName, singletonObject);
 * //删除三级缓存中的之
 * this.singletonFactories.remove(beanName);
 *
 * @param beanName            bean的名称
 * @param allowEarlyReference 是否允许暴露早期对象  通过该参数可以控制是否能够解决循环依赖的.
 * @return 这里可能返回一个null(IOC容器加载单实例bean的时候,第一次进来是返回null)
 * 也有可能返回一个单例对象(IOC容器加载了单实例了,第二次来获取当前的Bean)
 * 也可能返回一个早期对象(用于解决循环依赖问题)
 */
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   /**
    * 第一步:我们尝试去一级缓存(单例缓存池中去获取对象,一般情况从该map中获取的对象是直接可以使用的)
    * IOC容器初始化加载单实例bean的时候第一次进来的时候 该map中一般返回空
    */
   Object singletonObject = this.singletonObjects.get(beanName);
   /**
    * 若在第一级缓存中没有获取到对象,并且singletonsCurrentlyInCreation这个list包含该beanName
    * IOC容器初始化加载单实例bean的时候第一次进来的时候 该list中一般返回空,但是循环依赖的时候可以满足该条件
    */
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
         /**
          * 尝试去二级缓存中获取对象(二级缓存中的对象是一个早期对象)
          * 何为早期对象:就是bean刚刚调用了构造方法,还来不及给bean的属性进行赋值的对象
          * 就是早期对象
          */
         singletonObject = this.earlySingletonObjects.get(beanName);
         /**
          * 二级缓存中也没有获取到对象,allowEarlyReference为true(参数是有上一个方法传递进来的true)
          */
         if (singletonObject == null && allowEarlyReference) {
            /**
             * 直接从三级缓存中获取 ObjectFactory对象 这个对接就是用来解决循环依赖的关键所在
             * 在ioc后期的过程中,当bean调用了构造方法的时候,把早期对象包裹成一个ObjectFactory
             * 暴露到三级缓存中
             */
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            //从三级缓存中获取到对象不为空
            if (singletonFactory != null) {
               /**
                * 在这里通过暴露的ObjectFactory 包装对象中,通过调用他的getObject()来获取我们的早期对象
                * 在这个环节中会调用到 getEarlyBeanReference()来进行后置处理
                */
               singletonObject = singletonFactory.getObject();
               //把早期对象放置在二级缓存,
               this.earlySingletonObjects.put(beanName, singletonObject);
               //ObjectFactory 包装对象从三级缓存中删除掉
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}

// 该beanName对应的bean是否正在创建中,一般如果某个beanName存在循环依赖会返回true
public boolean isSingletonCurrentlyInCreation(String beanName) {
   return this.singletonsCurrentlyInCreation.contains(beanName);
}

getSingleton()流程图如下:

java 复制代码
/**
 * 一级缓存 这个就是我们大名鼎鼎的单例缓存池 用于保存我们所有的单实例bean
 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/**
 * 二级缓存 ,用户缓存我们的key为beanName value是我们的早期对象(对象属性还没有来得及进行赋值)
 */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

/**
 * 三级缓存 该map用户缓存 key为 beanName  value 为ObjectFactory(包装为早期对象)
 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

3. getObjectForBeanInstance

如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。但如果 sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的 bean 实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。

java 复制代码
protected Object getObjectForBeanInstance(
      Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
   
   // 如果 name 以 & 开头,但 beanInstance 却不是 FactoryBean,则认为有问题。
   if (BeanFactoryUtils.isFactoryDereference(name)) {
      if (beanInstance instanceof NullBean) {
         return beanInstance;
      }
      if (!(beanInstance instanceof FactoryBean)) {
         throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
      }
   }
   
   /**
    * 如果上面的判断通过了,表明 beanInstance 可能是一个普通的 bean,也可能是一个
    * FactoryBean。如果是一个普通的 bean,这里直接返回 beanInstance 即可。如果是
    * FactoryBean,则要调用工厂方法生成一个 bean 实例。
    */
   if (!(beanInstance instanceof FactoryBean) // 如果是一个普通的 bean,这里直接返回
         || BeanFactoryUtils.isFactoryDereference(name)) { // 如果是一个FactoryBean,并且name是&开头(说明你想返回的就是FactoryBean本身),直接返回
      return beanInstance;
   }
   
   // 执行到这里,说明beanInstance是一个FactoryBean
   Object object = null;
   if (mbd == null) {
      /**
       * 如果 mbd 为空,则从缓存中加载 bean。FactoryBean 生成的单例 bean 会被缓存
       * 在 factoryBeanObjectCache 集合中,不用每次都创建
       */
      object = getCachedObjectForFactoryBean(beanName);
   }
   if (object == null) {
      // 经过前面的判断,到这里可以保证 beanInstance 是 FactoryBean 类型的,所以可以进行类型转换
      FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
      // 如果 mbd 为空,则判断是否存在名字为 beanName 的 BeanDefinition
      if (mbd == null && containsBeanDefinition(beanName)) {
         mbd = getMergedLocalBeanDefinition(beanName);
      }
      // synthetic 字面意思是"合成的"。通过全局查找,我发现在 AOP 相关的类中会将该属性设为 true。
      // 所以我觉得该字段可能表示某个 bean 是不是被 AOP 增强过,也就是 AOP 基于原始类合成了一个新的代理类。
      // 不过目前只是猜测,没有深究
      boolean synthetic = (mbd != null && mbd.isSynthetic());
      //// 调用 getObjectFromFactoryBean 方法继续获取实例
      
      object = getObjectFromFactoryBean(factory, beanName, !synthetic);
   }
   return object;
}

protected Object getCachedObjectForFactoryBean(String beanName) {
   return this.factoryBeanObjectCache.get(beanName);
}

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
   /**
    * FactoryBean 也有单例和非单例之分,针对不同类型的 FactoryBean,这里有两种处理方式:
    *   1. 单例 FactoryBean 生成的 bean 实例也认为是单例类型。需放入缓存中,供后续重复使用
    *   2. 非单例 FactoryBean 生成的 bean 实例则不会被放入缓存中,每次都会创建新的实例
    **/
   if (factory.isSingleton() && containsSingleton(beanName)) {
      synchronized (getSingletonMutex()) {
         // 从缓存中取 bean 实例,避免多次创建 bean 实例
         Object object = this.factoryBeanObjectCache.get(beanName);
         if (object == null) {
            // 使用工厂对象中创建实例
            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) {
                  //判断当地的bean是否正在创建
                  if (isSingletonCurrentlyInCreation(beanName)) {
                     // Temporarily return non-post-processed object, not storing it yet..
                     return object;
                  }
                  beforeSingletonCreation(beanName);
                  try {
                     object = postProcessObjectFromFactoryBean(object, beanName);
                  } catch (Throwable ex) {
                     throw new BeanCreationException(beanName,
                           "Post-processing of FactoryBean's singleton object failed", ex);
                  } finally {
                     afterSingletonCreation(beanName);
                  }
               }
               // 这里的 beanName 对应于 FactoryBean 的实现类, FactoryBean 的实现类也会被实例化,并被缓存在 singletonObjects 中
               if (containsSingleton(beanName)) {
                  // 这里的 beanName 对应于 FactoryBean 的实现类, FactoryBean 的实现类也会被实例化,并被缓存在 singletonObjects 中
                  this.factoryBeanObjectCache.put(beanName, object);
               }
            }
         }
         return object;
      }
   } else {
      //prototype:每次拿的时候都会调用getObject方法创建新的对象,并不会把该对象存储到任何缓存中
      Object object = doGetObjectFromFactoryBean(factory, beanName);
      if (shouldPostProcess) {
         try {
            // 通过getObject()拿到的对象全部都是初始化完成的,调用初始化之后的bean的后置处理器
            object = postProcessObjectFromFactoryBean(object, beanName);
         } catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
         }
      }
      return object;
   }
}

4. getSingleton()

java 复制代码
/**
 * 获取单例对象(该流程用于触发构建bean)
 *
 * @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) {
         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马上就要被创建了
          * singletonsCurrentlyInCreation 在这里会把beanName加入进来,若第二次循环依赖(构造器注入会抛出异常)
          */
         beforeSingletonCreation(beanName);
         boolean newSingleton = false;
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }
         try {
            //<3> 初始化 bean
            // 这个过程其实是调用 createBean() 方法
            singletonObject = singletonFactory.getObject();
            newSingleton = true;
         } catch (IllegalStateException ex) {
            //回调我们singletonObjects的get方法,进行正在的创建bean的逻辑
            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;
            }
            // <4> 后置处理
            //主要做的事情就是把singletonsCurrentlyInCreation标记正在创建的bean从集合中移除
            afterSingletonCreation(beanName);
         }
         if (newSingleton) {
            // <5> 加入缓存中
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}

5. createBean

java 复制代码
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
   if (logger.isDebugEnabled()) {
      logger.debug("Creating instance of bean '" + beanName + "'");
   }
   RootBeanDefinition mbdToUse = mbd;
   
   // 确保此时的 bean 已经被解析了
   // 如果获取的class 属性不为null,则克隆该 BeanDefinition
   // 主要是因为该动态解析的 class 无法保存到到共享的 BeanDefinition
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }
   
   // Prepare method overrides.
   try {
      /**
       * 验证和准备覆盖方法
       * lookup-method 和 replace-method
       * 这两个配置存放在 BeanDefinition 中的 methodOverrides
       * 我们知道在 bean 实例化的过程中如果检测到存在 methodOverrides ,
       * 则会动态地位为当前 bean 生成代理并使用对应的拦截器为 bean 做增强处理。
       * 具体的实现我们后续分析,现在先看 mbdToUse.prepareMethodOverrides() 代码块
       */
      mbdToUse.prepareMethodOverrides();
   } catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }
   
   try {
      /**
       * 通过bean的后置处理器来进行后置处理生成代理对象,一般情况下在此处不会生成代理对象
       * 为什么不能生成代理对象,不管是我们的jdk代理还是cglib代理都不会在此处进行代理,因为我们的
       * 真实的对象没有生成,所以在这里不会生成代理对象,那么在这一步是我们aop和事务的关键,因为在这里
       * 解析我们的aop切面信息进行缓存
       */
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   } catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }
   
   try {
      /**
       * 该步骤是我们真正的创建我们的bean的实例对象的过程
       */
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isDebugEnabled()) {
         logger.debug("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);
   }
}

6. [第1次]resolveBeforeInstantiation()

后置处理器PostProcessor的【第一次】调用:bean实例化前调用。如果该方法不是返回一个null,那说明该对象已经被实例化并初始化完成了,用户表示不想继续走接下来的spring逻辑了,这个bean已经创建好了,接下来就调用bean初始化完成之后的回调了

@EnableAspectJAutoProxy导入 AnnotationAwareAspectJAutoProxyCreator @EnableTransactionManagement导入 InfrastructureAdvisorAutoProxyCreator。他们都会在这里postProcessBeforeInstantiation()进行后置处理解析切面

java 复制代码
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      //判断容器中是否有InstantiationAwareBeanPostProcessors
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         //获取当前bean 的class对象
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            /**
             * 后置处理器的【第一次】调用 总共有九处调用 事务在这里不会被调用,aop的才会被调用
             * 为啥aop在这里调用了,因为在此处需要解析出对应的切面保存到缓存中
             */
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            //若InstantiationAwareBeanPostProcessors后置处理器的postProcessBeforeInstantiation返回不为null
            
            //说明生成了代理对象那么我们就调用
            if (bean != null) {
               /**
                * 后置处理器的第二处调用,该后置处理器若被调用的话,那么第一处的处理器肯定返回的不是null
                * InstantiationAwareBeanPostProcessors后置处理器postProcessAfterInitialization
                */
               
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         /**
          * 【很重要】
          * 我们AOP @EnableAspectJAutoProxy 为我们容器中导入了 AnnotationAwareAspectJAutoProxyCreator
          * 我们事务注解@EnableTransactionManagement 为我们的容器导入了 InfrastructureAdvisorAutoProxyCreator
          * 都是实现了我们的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
          * 进行后置处理解析切面
          */
         Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
         if (result != null) {
            return result;
         }
      }
   }
   return null;
}

7. doCreateBean

真正创建bean的逻辑

该方法是最复杂的包含了调用构造函数:给bean的属性赋值、调用bean的初始化操作以及 生成代理对象都是在这里

java 复制代码
/**
 * 真的创建bean的逻辑,该方法是最复杂的包含了调用构造函数,给bean的属性赋值
 * 调用bean的初始化操作以及 生成代理对象 都是在这里
 *
 * @param beanName bean的名称
 * @param mbd      bean的定义
 * @param args     传入的参数
 * @return 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 {
   //BeanWrapper 是对 Bean 的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装 bean 的属性描述器
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      //从没有完成的FactoryBean中移除
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      //使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化 该方法很复杂也很重要
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   //从beanWrapper中获取我们的早期对象
   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 {
            //进行后置处理 @Autowired的注解的预解析
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         } catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex);
         }
         mbd.postProcessed = true;
      }
   }
   
   /**
    * 该对象进行判断是否能够暴露早期对象的条件
    * 单实例
    * this.allowCircularReferences 默认为true
    * isSingletonCurrentlyInCreation(表示当前的bean对象正在创建 singletonsCurrentlyInCreation包含当前正在创建的bean)
    */
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
   //上述条件满足,允许中期暴露对象
   if (earlySingletonExposure) {
      if (logger.isDebugEnabled()) {
         logger.debug("Eagerly caching bean '" + beanName +
               "' to allow for resolving potential circular references");
      }
      /**
       * 
       *  Spring 在实例化对象的之后,就会为其创建一个 Bean 工厂,并将此工厂加入到三级缓存中。
       * 因此,Spring 一开始提前暴露的并不是实例化的 Bean,而是将 Bean 包装起来的 ObjectFactory。为什么要这么做呢?
       * 这实际上涉及到 AOP,如果创建的 Bean 是有代理的,那么注入的就应该是代理 Bean,而不是原始的 Bean。但是 Spring 一开始并不知道 Bean 是否会有循环依赖,
       * 通常情况下(没有循环依赖的情况下),Spring 都会在完成填充属性,并且执行完初始化方法之后再为其创建代理。
       * 但是,如果出现了循环依赖的话,Spring 就不得不为其提前创建代理对象,否则注入的就是一个原始对象,而不是代理对象。因此,这里就涉及到应该在哪里提前创建代理对象?
       * Spring 的做法就是在 ObjectFactory 中去提前创建代理对象。它会执行 getObject() 方法来获取到 Bean。
       * ////////////////////////////////////
       * Spring 需要三级缓存的目的是为了在没有循环依赖的情况下,延迟代理对象的创建,使 Bean 的创建符合 Spring 的设计原则
       * ////////////////////////////////////
       */
      //把我们的早期对象包装成一个singletonFactory对象 该对象提供了一个getObject方法,该方法内部调用getEarlyBeanReference方法丢入到第三级缓存中了
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }
   
   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      //给我们的属性进行赋值(调用set方法进行赋值)
      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) {
      /**
       * 去缓存中获取到我们的对象 由于传递的allowEarlyReferce 是false 要求只能在一级二级缓存中去获取
       * 正常普通的bean(不存在循环依赖的bean) 创建的过程中,压根不会把三级缓存提升到二级缓存中
       */
      
      Object earlySingletonReference = getSingleton(beanName, false);
      //能够获取到
      if (earlySingletonReference != null) {
         //经过后置处理的bean和早期的bean引用还相等的话(表示当前的bean没有被代理过)
         if (exposedObject == bean) {
            exposedObject = earlySingletonReference;
         }
         //处理依赖的bean
         else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
            // 获取beanName依赖的的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的销毁接口
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   } catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
   }
   
   return exposedObject;
}

8. [第2次]determineConstructorsFromBeanPostProcessors()

后置处理器PostProcessor的【第二次】调用:确定要用于给定bean的候选构造函数。每一个bean都可以有多个构造器,但是必须让spring知道使用哪一个构造器去实例化该对象

一个bean可能有很多个构造器,此方法用来返回特定的一个构造器,届时会使用该构造器创建bean。

只有AutowiredAnnotationBeanPostProcessor回调过该方法,用于解析@Autowired和预解析@LookUp

java 复制代码
/**
 * 通过SmartInstantiationAwareBeanPostProcessor的后置处理器的determineCandidateConstructors来查找出对应的构造函数
 * {@link SmartInstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessors}.
 * {
 * ConfigurationCLassPostProcessor$ImportAwareBeanPostProcessor
 * AutoWiredAnnotationBeanPostProceesor(处理@AutoWired规范的后置处理器)
 * }
 *
 * @param beanClass 当前bean的class对象
 * @param beanName  当前bean的名称
 * @return the candidate constructors,返回一个候选的构造函数或者是null
 * @throws org.springframework.beans.BeansException in case of errors
 * @see org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
 */
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
      throws BeansException {
   if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
      //获取到容器中所有的后置处理器BeanPostProcessors
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
            //调用我们后置处理器的determineCandidateConstructors 来决定我们的构造方法
            Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
            if (ctors != null) {
               return ctors;
            }
         }
      }
   }
   return null;
}

9. [第3次]applyMergedBeanDefinitionPostProcessors()

后置处理器PostProcessor的【第三次】调用:为指定的bean后处理给定的合并bean定义。给个机会给用户修改beanDefinition

AutowiredAnnotationBeanPostProcessor回调过该方法,预解析beanClass中的成员属性或者成员方法(标注了@Autowired@Value@Inject三者中任意一个)

CommonAnnotationBeanPostProcessor回调过该方法,预解析@PostConstruct@PreDestroy的方法、预解析@Resource的成员方法和成员属性

java 复制代码
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);
      }
   }
}

10. addSingletonFactory

Spring 在实例化对象的之后,就会为其创建一个 Bean 工厂,并将此工厂加入到三级缓存中。

因此,Spring 一开始提前暴露的并不是实例化的 Bean,而是将 Bean 包装起来的 ObjectFactory。为什么要这么做呢?

这实际上涉及到 AOP,如果创建的 Bean 是有代理的,那么注入的就应该是代理 Bean,而不是原始的 Bean。但是 Spring 一开始并不知道 Bean 是否会有循环依赖,通常情况下(没有循环依赖的情况下),Spring 都会在完成填充属性,并且执行完初始化方法之后再为其创建代理。但是如果出现了循环依赖的话,Spring 就不得不为其提前创建代理对象,否则注入的就是一个原始对象,而不是代理对象。因此,这里就涉及到应该在哪里提前创建代理对象。

Spring 的做法就是在 ObjectFactory 中去提前创建代理对象。它会执行getObject() 方法来获取到 Bean。

Spring 需要三级缓存的目的是为了在没有循环依赖的情况下,延迟代理对象的创建,使 Bean 的创建符合 Spring 的设计原则

java 复制代码
/**
 * 该方法用于把早期对象包装成一个ObjectFactory 暴露到三级缓存中 用于将解决循环依赖...
 *
 * @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) {
      //单例缓存池中没有包含当前的bean
      if (!this.singletonObjects.containsKey(beanName)) {
         //加入到三级缓存中,,,,,暴露早期对象用于解决循环依赖
         this.singletonFactories.put(beanName, singletonFactory);
         this.earlySingletonObjects.remove(beanName);
         this.registeredSingletons.add(beanName);
      }
   }
}

11. [第4次]getEarlyBeanReference

后置处理器PostProcessor的【第四次】调用:生成当前bean的早期引用对象

这个方法很重要 网上大多数人都没有说清楚,在解决循环依赖的过程中把三级对象的getObject()的时候,会触发getEarlyBeanReference。

在该方法中,我们可以通过SmartInstantiationAwareBeanPostProcessor的后置处理器来修改我们早期对象的属性,但是spring内部的SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference没有做任何的处理正符合spring开放式接口规范 留给我们扩展

AbstractAutoProxyCreator回调过该方法,如果当前对象有Adviros的话,就在此为当前对象创建代理对象

java 复制代码
/**
 * 这个方法很重要 网上大多数人都没有说清楚,在解决循环依赖的过程中把三级对象的getObject()的时候,会触发getEarlyBeanReference
 * 在该方法中,我们可以通过SmartInstantiationAwareBeanPostProcessor的后置处理器来修改我们早期对象的属性,
 * 但是spring内部的SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference没有做任何的处理
 * 正符合spring开放式接口规范 留给我们扩展
 *
 * @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;
   //判读我们容器中是否有InstantiationAwareBeanPostProcessors类型的后置处理器
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      //获取我们所有的后置处理器
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         //判断我们的后置处理器是不是实现了SmartInstantiationAwareBeanPostProcessor接口
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
            //进行强制转换
            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
            //挨个调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference
            exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
         }
      }
   }
   return exposedObject;
}

12. [第5次、第六次]populateBean

后置处理器PostProcessor的【第五次】调用:让用户可以自定义属性注入。一般返回true

InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()该方法如果返回false,说明不用spring帮忙注入属性了,代表属性填充完成。就是给个机会让用户可以自定义属性注入,对该方法的具体解释如下: 在属性被填充前,给InstantiationAwareBeanPostProcessor类型的后置处理器一个修改bean 状态的机会。官方的解释是:让用户可以自定义属性注入。比如用户实现一 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过 postProcessAfterInstantiation() 方法向 bean 的成员变量注入自定义的信息。

当时我们发现spring中的的InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation没有进行任何处理,若我们自己实现了这个接口 可以自定义处理

spring 留给我们自己扩展接口的特殊需求,直接使用配置中的信息注入即可。

后置处理器PostProcessor的【第六次】调用InstantiationAwareBeanPostProcessor#postProcessPropertyValues

AutowiredAnnotationBeanPostProcessor回调过该方法,为标注了@Autowired@Value@Inject三者中任意一个的属性或方法赋值

CommonAnnotationBeanPostProcessor回调过该方法,为标注了@Resource的属性或方法赋值

RequiredAnnotationBeanPostProcessor回调过该方法,确保那些标记了@Required的set方法被调用过,可以看做是一个校验,可以忽略不看

java 复制代码
/**
 * 给我们的对象BeanWrapper赋值
 *
 * @param beanName bean的名称
 * @param mbd      bean的定义
 * @param bw       bean实例包装对象
 */
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   //若bw为null的话,则说明对象没有实例化
   if (bw == null) {
      //进入if 说明对象有属性,bw为空,不能为他设置属性,那就在下面就执行抛出异常
      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;
      }
   }
   
   /**
    * 在属性被填充前,给 InstantiationAwareBeanPostProcessor 类型的后置处理器一个修改
    * bean 状态的机会。官方的解释是:让用户可以自定义属性注入。比如用户实现一
    * 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过
    * postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。
    *当时我们发现系统中的的InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation没有进行任何处理,
    *若我们自己实现了这个接口 可以自定义处理.....spring 留给我们自己扩展接口的
    *特殊需求,直接使用配置中的信息注入即可。
    */
   boolean continueWithPropertyPopulation = true;
   //是否持有 InstantiationAwareBeanPostProcessor
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      //获取容器中的所有的BeanPostProcessor
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            //若存在后置处理器给我们属性赋值了,那么返回false 可以来修改我们的开关变量,就不会走下面的逻辑了
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               // 返回值为是否继续填充 bean
               // postProcessAfterInstantiation:如果应该在 bean上面设置属性则返回 true,否则返回 false
               // 一般情况下,应该是返回true 。
               // 返回 false 的话,将会阻止在此 Bean 实例上调用任何后续的 InstantiationAwareBeanPostProcessor 实
               continueWithPropertyPopulation = false;
               break;
            }
         }
      }
   }
   // 如果后续处理器发出停止填充命令,则终止后续操作
   if (!continueWithPropertyPopulation) {
      return;
   }
   
   //获取bean定义的属性
   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
   
   /**
    * 判断我们的bean的属性注入模型
    * AUTOWIRE_BY_NAME 根据名称注入
    * AUTOWIRE_BY_TYPE 根据类型注入
    */
   
   if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
      //把PropertyValues封装成为MutablePropertyValues
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      //根据bean的属性名称注入
      if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }
      //根据bean的类型进行注入
      if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
         autowireByType(beanName, mbd, bw, newPvs);
      }
      //把处理过的 属性覆盖原来的
      pvs = newPvs;
   }
   
   /**
    * 这里又是一种后置处理,用于在 Spring 填充属性到 bean 对象前,对属性的值进行相应的处理,
    * 比如可以修改某些属性的值。这时注入到 bean 中的值就不是配置文件中的内容了,
    * 而是经过后置处理器修改后的内容
    */
   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   //判断是否需要检查依赖
   boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
   
   if (hasInstAwareBpps || needsDepCheck) {
      if (pvs == null) {
         pvs = mbd.getPropertyValues();
      }
      //提出当前正在创建的beanWrapper 依赖的对象
      PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      if (hasInstAwareBpps) {
         //获取所有的后置处理器
         for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
               //对依赖对象进行后置处理
               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvs == null) {
                  return;
               }
            }
         }
      }
      //判断是否检查依赖
      if (needsDepCheck) {
         checkDependencies(beanName, mbd, filteredPds, pvs);
      }
   }
   
   /**
    * 其实,上面只是完成了所有注入属性的获取,将获取的属性封装在 PropertyValues 的实例对象 pvs 中,
    * 并没有应用到已经实例化的 bean 中。而 #applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) 方法,
    * 则是完成这一步骤的
    */
   if (pvs != null) {
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

13. initializeBean()

java 复制代码
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 {
      //若我们的bean实现了XXXAware接口进行方法的回调
      invokeAwareMethods(beanName, bean);
   }
   
   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      //调用我们的bean的后置处理器的postProcessorsBeforeInitialization方法  @PostCust注解的方法
      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()) {
      //调用我们bean的后置处理器的PostProcessorsAfterInitialization方法
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   
   return wrappedBean;
}

private void invokeAwareMethods(final String beanName, final Object bean) {
   if (bean instanceof Aware) {
      //我们的bean实现了BeanNameAware
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      //实现了BeanClassLoaderAware接口
      if (bean instanceof BeanClassLoaderAware) {
         ClassLoader bcl = getBeanClassLoader();
         if (bcl != null) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
         }
      }
      //实现了BeanFactoryAware
      if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}

14. [第7次]applyBeanPostProcessorsBeforeInitialization()

后置处理器PostProcessor的【第七次】调用 :bean初始化前的回调 BeanPostProcessor#postProcessBeforeInitialization

ApplicationContextAwareProcessor回调过该方法,如果有bean实现了以下接口,那么会在这一步自动为当前bean设置Aware实例,它们是: EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware

CommonAnnotationBeanPostProcessor回调过该方法,反射调用被注解@PostConstruct标记的方法

LoadTimeWeaverAwareProcessor 回调过该方法,如果有bean实现了LoadTimeWeaverAware接口,那么会在这一步自动为当前bean设置LoadTimeWeaverAware实例,该Processor默认不启用,需要通过注解 @EnableLoadTimeWeaving手动启用

ServletContextAwareProcessor 回调过该方法,如果有bean实现了ServletContextAwareServletConfigAware接口,那么会在这一步自动为当前bean设置ServletContextServletConfig实例

java 复制代码
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      throws BeansException {
   
   Object result = existingBean;
   //获取我们容器中的所有的bean的后置处理器
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      //挨个调用我们的bean的后置处理器的postProcessBeforeInitialization
      Object current = processor.postProcessBeforeInitialization(result, beanName);
      //若只有有一个返回null 那么直接返回原始的
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

15. invokeInitMethods

  1. 回调InitializingBean#afterPropertiesSet()
  2. 回调bean的自定义init方法
java 复制代码
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
      throws Throwable {
   
   //判断我们的容器中是否实现了InitializingBean接口
   boolean isInitializingBean = (bean instanceof InitializingBean);
   if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
      if (logger.isDebugEnabled()) {
         logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      if (System.getSecurityManager() != null) {
         try {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((InitializingBean) bean).afterPropertiesSet();
               return null;
            }, getAccessControlContext());
         } catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      } else {
         //回调InitializingBean的afterPropertiesSet()方法
         ((InitializingBean) bean).afterPropertiesSet();
      }
   }
   
   if (mbd != null && bean.getClass() != NullBean.class) {
      //我们beanclass中看是否有自己定义的init方法
      String initMethodName = mbd.getInitMethodName();
      //判断自定义的init方法名称不叫afterPropertiesSet
      if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
         //调用我们自己的初始化方法
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}

16. [第8次]applyBeanPostProcessorsAfterInitialization()

后置处理器PostProcessor的【第八次】调用:bean初始化完成之后的回调

【很重要】:

@EnableAspectJAutoProxy导入AnnotationAwareAspectJAutoProxyCreator

@EnableTransactionManagement导入了InfrastructureAdvisorAutoProxyCreator

他们都实现了我们的 BeanPostProcessor接口

InstantiationAwareBeanPostProcessor,在这里实现的是BeanPostProcessor接口的postProcessAfterInitialization来生成我们的代理对象

java 复制代码
ApplicationListenerDetector

ScheduledAnnotationBeanPostProcessor

BeanValidationPostProcessor


AbstractAdvisingBeanPostProcessor

AbstractAutoProxyCreator
java 复制代码
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {
   
   Object result = existingBean;
   //获取我们容器中的所有的bean的后置处理器
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      /**
       * 在这里是后置处理器的【第九次调用】 aop和事务都会在这里生存代理对象
       *
       * 【很重要】
       * 我们AOP @EnableAspectJAutoProxy 为我们容器中导入了 AnnotationAwareAspectJAutoProxyCreator
       * 我们事务注解@EnableTransactionManagement 为我们的容器导入了 InfrastructureAdvisorAutoProxyCreator
       * 都是实现了我们的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
       * 在这里实现的是BeanPostProcessor接口的postProcessAfterInitialization来生成我们的代理对象
       */
      Object current = processor.postProcessAfterInitialization(result, beanName);
      //若只有有一个返回null 那么直接返回原始的
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

17. [第9次]destroy()

后置处理器PostProcessor的【第九次】调用 :bean销毁前的回调 DestructionAwareBeanPostProcessor#postProcessBeforeDestruction

java 复制代码
@Override
public void destroy() {
   if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
      for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
         processor.postProcessBeforeDestruction(this.bean, this.beanName);
      }
   }

   if (this.invokeDisposableBean) {
      if (logger.isDebugEnabled()) {
         logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
      }
      try {
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((DisposableBean) this.bean).destroy();
               return null;
            }, this.acc);
         }
         else {
            ((DisposableBean) this.bean).destroy();
         }
      }
      catch (Throwable ex) {
         String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
         if (logger.isDebugEnabled()) {
            logger.warn(msg, ex);
         }
         else {
            logger.warn(msg + ": " + ex);
         }
      }
   }

   if (this.destroyMethod != null) {
      invokeCustomDestroyMethod(this.destroyMethod);
   }
   else if (this.destroyMethodName != null) {
      Method methodToCall = determineDestroyMethod(this.destroyMethodName);
      if (methodToCall != null) {
         invokeCustomDestroyMethod(methodToCall);
      }
   }
}

spring ioc 加载流程图

相关推荐
m0_7482451730 分钟前
Web第一次作业
java
小码的头发丝、30 分钟前
Java进阶学习笔记|面向对象
java·笔记·学习
m0_5485147733 分钟前
前端Pako.js 压缩解压库 与 Java 的 zlib 压缩与解压 的互通实现
java·前端·javascript
坊钰1 小时前
【Java 数据结构】移除链表元素
java·开发语言·数据结构·学习·链表
chenziang11 小时前
leetcode hot100 LRU缓存
java·开发语言
会说法语的猪1 小时前
springboot实现图片上传、下载功能
java·spring boot·后端
码农老起1 小时前
IntelliJ IDEA 基本使用教程及Spring Boot项目搭建实战
java·ide·intellij-idea
m0_748239831 小时前
基于web的音乐网站(Java+SpringBoot+Mysql)
java·前端·spring boot
时雨h1 小时前
RuoYi-ue前端分离版部署流程
java·开发语言·前端