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 加载流程图

相关推荐
DuelCode1 小时前
Windows VMWare Centos Docker部署Springboot 应用实现文件上传返回文件http链接
java·spring boot·mysql·nginx·docker·centos·mybatis
优创学社21 小时前
基于springboot的社区生鲜团购系统
java·spring boot·后端
why技术1 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
幽络源小助理1 小时前
SpringBoot基于Mysql的商业辅助决策系统设计与实现
java·vue.js·spring boot·后端·mysql·spring
猴哥源码1 小时前
基于Java+springboot 的车险理赔信息管理系统
java·spring boot
YuTaoShao2 小时前
【LeetCode 热题 100】48. 旋转图像——转置+水平翻转
java·算法·leetcode·职场和发展
ai小鬼头2 小时前
AIStarter如何助力用户与创作者?Stable Diffusion一键管理教程!
后端·架构·github
Dcs2 小时前
超强推理不止“大”——手把手教你部署 Mistral Small 3.2 24B 大模型
java
简佐义的博客2 小时前
破解非模式物种GO/KEGG注释难题
开发语言·数据库·后端·oracle·golang
东阳马生架构2 小时前
订单初版—1.分布式订单系统的简要设计文档
java