zoukankan      html  css  js  c++  java
  • 3.2spring源码系列----循环依赖源码分析

    首先,我们在3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 中手写了循环依赖的实现. 这个实现就是模拟的spring的循环依赖. 目的是为了更容易理解spring源码.

    下面我们就进入正题, 看看spring的循环依赖源码.

    一、getBean整体流程

    目标很明确了, 就是要看看spring如何解决循环依赖的. 

    代码入口是refresh()#finishBeanFactoryInitialization(beanFactory);

    二、拆解研究流程中的每一步

    调用方法beanFactory.preInstantiateSingletons();实例化剩余的单例bean. 为什么是剩余的?很显然我们在上面已经实例化一部分了.比如配置类, postProcessor等.

    2.1 入口

    1 @Override
     2     public void preInstantiateSingletons() throws BeansException {
     3         if (logger.isTraceEnabled()) {
     4             logger.trace("Pre-instantiating singletons in " + this);
     5         }
     6 
     7 
     8         // 获取容器中所有bean定义的名字
     9         List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    10 
    11         // Trigger initialization of all non-lazy singleton beans...
    12         /**
    13          * 第一步: 循环bean定义的name
    14          */
    15         for (String beanName : beanNames) {
    16             // 获取bean定义
    17             RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    18             // 生产bean定义的条件: 不是抽象的, 是单例的, 不是懒加载的. 符合这个标准的, 最后才会调用getBean()生产bean
    19             if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    20                 // 这里判断是不是工厂bean, 这里和BeanFactory不是一个意思, 判断当前这个bean是否实现了beanFactory的接口
    21                 if (isFactoryBean(beanName)) {
    22                     Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
    23                     if (bean instanceof FactoryBean) {
    24                         final FactoryBean<?> factory = (FactoryBean<?>) bean;
    25                         boolean isEagerInit;
    26                         if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
    27                             isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
    28                                             ((SmartFactoryBean<?>) factory)::isEagerInit,
    29                                     getAccessControlContext());
    30                         }
    31                         else {
    32                             isEagerInit = (factory instanceof SmartFactoryBean &&
    33                                     ((SmartFactoryBean<?>) factory).isEagerInit());
    34                         }
    35                         if (isEagerInit) {
    36                             // 获取bean
    37                             getBean(beanName);
    38                         }
    39                     }
    40                 }
    41                 else {
                  // 第二步: 调用bean定义
    42                     getBean(beanName);
    43                 }
    44             }
    45         }
    46 
    47         // Trigger post-initialization callback for all applicable beans...
    48         
    51         for (String beanName : beanNames) {
    52             // 从缓存中得到实例instance
    53             Object singletonInstance = getSingleton(beanName);
    54             if (singletonInstance instanceof SmartInitializingSingleton) {
    55                 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
    56                 if (System.getSecurityManager() != null) {
    57                     AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    58                         smartSingleton.afterSingletonsInstantiated();
    59                         return null;
    60                     }, getAccessControlContext());
    61                 }
    62                 else {
    63                     smartSingleton.afterSingletonsInstantiated();
    64                 }
    65             }
    66         }
    67     }

    首先, 循环bean定义, 这和我们模拟spring循环的第一步是一样的. 

    第二步: 判断从BeanDefinitionMap中取出来的这个bean是否满足生产bean的条件

    我们注意代码注释中, 生产bean定义的条件: 不是抽象的, 是单例的, 不是懒加载的. 符合这个标准的, 最后才会调用getBean()生产bean

    然后:调用getBean()

    到目前为止,我们完成了上图源码图的第一部分:

     2.2 创建bean前的准备工作

    接下来看看getBean().doGetBean()方法

    1 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      2             @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
      3 
      4         // 第一步: 转换bean name. 在这里传入进来的name可能是别名, 也有可能是工厂bean的name, 所以在这里进行一个转换
      5         final String beanName = transformedBeanName(name);
      6         Object bean;
      7 
      8         // Eagerly check singleton cache for manually registered singletons.
      9         // 第二步: 尝试去缓存中获取对象, 如果没有获取到就创建bean
     10         Object sharedInstance = getSingleton(beanName);
     11         if (sharedInstance != null && args == null) {
     12             if (logger.isTraceEnabled()) {
     13                 //判断当前类是否是正在创建中
     14                 if (isSingletonCurrentlyInCreation(beanName)) {
     15                     logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
     16                             "' that is not fully initialized yet - a consequence of a circular reference");
     17                 }
     18                 else {
     19                     logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
     20                 }
     21             }
     22             bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
     23         }
     24 
     25         else {
     26             // Fail if we're already creating this bean instance:
     27             // We're assumably within a circular reference.
     28             /**
     29              * 判断当前的bean是不是多例, 如果是这抛出异常
     30              *
     31              * 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
     32              * spring 只能解决单例对象的setter注入的循环依赖, 不能解决构造器注入
     33              *
     34              * 如果是多例的bean, 当前正在创建bean, 也会抛出异常---这也是循环依赖的问题
     35              */
     36             if (isPrototypeCurrentlyInCreation(beanName)) {
     37                 throw new BeanCurrentlyInCreationException(beanName);
     38             }
     39 
     40             /**
     41              * 下面这段代码是关于子父容器的, 只有spring mvc继承自spring, 才会有子父容器的问题.
     42              */
     43             // Check if bean definition exists in this factory.
     44             BeanFactory parentBeanFactory = getParentBeanFactory();
     45             if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
     46                 // Not found -> check parent.
     47                 String nameToLookup = originalBeanName(name);
     48                 if (parentBeanFactory instanceof AbstractBeanFactory) {
     49                     return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
     50                             nameToLookup, requiredType, args, typeCheckOnly);
     51                 }
     52                 else if (args != null) {
     53                     // Delegation to parent with explicit args.
     54                     return (T) parentBeanFactory.getBean(nameToLookup, args);
     55                 }
     56                 else if (requiredType != null) {
     57                     // No args -> delegate to standard getBean method.
     58                     return parentBeanFactory.getBean(nameToLookup, requiredType);
     59                 }
     60                 else {
     61                     return (T) parentBeanFactory.getBean(nameToLookup);
     62                 }
     63             }
     64 
     65             /**
     66              * 方法参数typeCheckOnly是用来判断#getBean()方法时, 表示是否为仅仅进行类型检查,
     67              * 如果不仅仅做类型检查, 而是创建bean对象, 则需要调用#markBeanAsCreated(String name)
     68              *
     69              */
     70             if (!typeCheckOnly) {
     71                 markBeanAsCreated(beanName);
     72             }
     73 
     74             try {
     75                 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
     76                 checkMergedBeanDefinition(mbd, beanName, args);
     77 
     78                 // Guarantee initialization of beans that the current bean depends on.
     79                 /**
     80                  * 现在有两个bean1, bean2 , 加载的时候调用的是bean1, bean2. 但如果我们想要bean2优先加载, 就使用@DependOn注解
     81                  * 用来解析带有dependOn注解的类
     82                  */
     83                 String[] dependsOn = mbd.getDependsOn();
     84                 if (dependsOn != null) {
     85                     for (String dep : dependsOn) {
     86                         if (isDependent(beanName, dep)) {
     87                             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     88                                     "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
     89                         }
     90                         registerDependentBean(dep, beanName);
     91                         try {
     92                             getBean(dep);
     93                         }
     94                         catch (NoSuchBeanDefinitionException ex) {
     95                             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     96                                     "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
     97                         }
     98                     }
     99                 }
    100 
    101                 // Create bean instance.
    102                 /**
    103                  * 第三步: 创建单例bean实例
    104                  */
    105                 if (mbd.isSingleton()) { // 处理单例bean
    106                     /**
    107                      * 这里getSingleton()和上面的getSigleton不一样, 上面的是从一级缓存中拿.
    108                      * 这个getSingleton()就办了一件事: 将bean设置为正在创建的状态. 这个状态很重要, 如果出现循环依赖, 发现bean正在创建, 就不会再创建了
    109                      */
    110                     sharedInstance = getSingleton(beanName, () -> {
    111                         try {
    112                             return createBean(beanName, mbd, args);
    113                         }
    114                         catch (BeansException ex) {
    115                             // Explicitly remove instance from singleton cache: It might have been put there
    116                             // eagerly by the creation process, to allow for circular reference resolution.
    117                             // Also remove any beans that received a temporary reference to the bean.
    118                             destroySingleton(beanName);
    119                             throw ex;
    120                         }
    121                     });
    122                     // 得到bean实例对象
    123                     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    124                 }
    125 
    126                 else if (mbd.isPrototype()) { // 处理多例bean
    127                     // It's a prototype -> create a new instance.
    128                     Object prototypeInstance = null;
    129                     try {
    130                         // 当前正在创建多例bean
    131                         beforePrototypeCreation(beanName);
    132                         // 执行创建bean
    133                         prototypeInstance = createBean(beanName, mbd, args);
    134                     }
    135                     finally {
    136                         afterPrototypeCreation(beanName);
    137                     }
    138                     // 获取bean实例对象
    139                     bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    140                 }
    141 
    142                 else { // 处理其他类型的bean
    143                     String scopeName = mbd.getScope();
    144                     final Scope scope = this.scopes.get(scopeName);
    145                     if (scope == null) {
    146                         throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
    147                     }
    148                     try {
    149                         Object scopedInstance = scope.get(beanName, () -> {
    150                             beforePrototypeCreation(beanName);
    151                             try {
    152                                 return createBean(beanName, mbd, args);
    153                             }
    154                             finally {
    155                                 afterPrototypeCreation(beanName);
    156                             }
    157                         });
    158                         bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    159                     }
    160                     catch (IllegalStateException ex) {
    161                         throw new BeanCreationException(beanName,
    162                                 "Scope '" + scopeName + "' is not active for the current thread; consider " +
    163                                 "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
    164                                 ex);
    165                     }
    166                 }
    167             }
    168             catch (BeansException ex) {
    169                 cleanupAfterBeanCreationFailure(beanName);
    170                 throw ex;
    171             }
    172         } 

    在这里, 首先从缓存中获取bean, 看缓存中是否已经存在了

     Object sharedInstance = getSingleton(beanName);

    然后, 如果缓存中已经存在了,那么久直接取出来. 代码如下: 

        if (sharedInstance != null && args == null) {
                if (logger.isTraceEnabled()) {
                    //判断当前bean是否是正在创建中(单例bean)
                    if (isSingletonCurrentlyInCreation(beanName)) {
                        logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                                "' that is not fully initialized yet - a consequence of a circular reference");
                    }
                    else {
                        logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                    }
                }
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
            }

    如果是空, 就说明是第一次创建, 执行else的部分

    首先, 判断是否是正在创建的多例bean, 如果是正在创建的多例bean, 就抛出异常,

      已经是正在创建了, 说明这至少是第二次了, 这里处理的是单例bean的循环依赖, 不处理多例bean的循环依赖, 所以抛出异常

      对应的代码是这一句

      

    // Fail if we're already creating this bean instance:
     27             // We're assumably within a circular reference.
     28             /**
     29              * 判断当前的bean是不是多例, 如果是这抛出异常
     30              *
     31              * 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
     32              * spring 只能解决单例对象的setter注入的循环依赖, 不能解决构造器注入
     33              *
     34              * 如果是多例的bean, 当前正在创建bean, 也会抛出异常---这也是循环依赖的问题
     35              */
     36             if (isPrototypeCurrentlyInCreation(beanName)) {
     37                 throw new BeanCurrentlyInCreationException(beanName);
     38             }

    那么, 接下来就是首次创建bean. 首次创建的bean有三种情况:

      第一种, 这个bean是单例的.

      第二种, 这个bean是多例的.

      第三种. 其他类型

    对应的代码就是这一块. 有行号, 可以和上面一一对应上

    // Create bean instance.
    102                 /**
    103                  * 第三步: 创建单例bean实例
    104                  */
    105                 if (mbd.isSingleton()) { // 处理单例bean
    106                     /**
    107                      * 这里getSingleton()和上面的getSigleton不一样, 上面的是从一级缓存中拿.
    108                      * 这个getSingleton()就办了一件事: 将bean设置为正在创建的状态. 这个状态很重要, 如果出现循环依赖, 发现bean正在创建, 就不会再创建了
    109                      */
    110                     sharedInstance = getSingleton(beanName, () -> {
    111                         try {
    112                             return createBean(beanName, mbd, args);
    113                         }
    114                         catch (BeansException ex) {
    115                             // Explicitly remove instance from singleton cache: It might have been put there
    116                             // eagerly by the creation process, to allow for circular reference resolution.
    117                             // Also remove any beans that received a temporary reference to the bean.
    118                             destroySingleton(beanName);
    119                             throw ex;
    120                         }
    121                     });
    122                     // 得到bean实例对象
    123                     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    124                 }
    125 
    126                 else if (mbd.isPrototype()) { // 处理多例bean
    127                     // It's a prototype -> create a new instance.
    128                     Object prototypeInstance = null;
    129                     try {
    130                         // 当前正在创建多例bean
    131                         beforePrototypeCreation(beanName);
    132                         // 执行创建bean
    133                         prototypeInstance = createBean(beanName, mbd, args);
    134                     }
    135                     finally {
    136                         afterPrototypeCreation(beanName);
    137                     }
    138                     // 获取bean实例对象
    139                     bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    140                 }
    141 
    142                 else { // 处理其他类型的bean
    143                     String scopeName = mbd.getScope();
    144                     final Scope scope = this.scopes.get(scopeName);
    145                     if (scope == null) {
    146                         throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
    147                     }
    148                     try {
    149                         Object scopedInstance = scope.get(beanName, () -> {
    150                             beforePrototypeCreation(beanName);
    151                             try {
    152                                 return createBean(beanName, mbd, args);
    153                             }
    154                             finally {
    155                                 afterPrototypeCreation(beanName);
    156                             }
    157                         });
    158                         bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    159                     }
    160                     catch (IllegalStateException ex) {
    161                         throw new BeanCreationException(beanName,
    162                                 "Scope '" + scopeName + "' is not active for the current thread; consider " +
    163                                 "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
    164                                 ex);
    165                     }
    166                 }

    我们的重点研究对象是单例bean. 所以,重点看单例bean的实现

    105                 if (mbd.isSingleton()) { // 处理单例bean
    106                     /**
    107                      * 这里getSingleton()和上面的getSigleton不一样, 上面的是从一级缓存中拿.
    108                      * 这个getSingleton()就办了一件事: 将bean设置为正在创建的状态. 这个状态很重要, 如果出现循环依赖, 发现bean正在创建, 就不会再创建了
    109                      */
    110                     sharedInstance = getSingleton(beanName, () -> {
    111                         try {
    112                             return createBean(beanName, mbd, args);
    113                         }
    114                         catch (BeansException ex) {
    115                             // Explicitly remove instance from singleton cache: It might have been put there
    116                             // eagerly by the creation process, to allow for circular reference resolution.
    117                             // Also remove any beans that received a temporary reference to the bean.
    118                             destroySingleton(beanName);
    119                             throw ex;
    120                         }
    121                     });
    122                     // 得到bean实例对象
    123                     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    124                 }

    这里的重点是调用了getSingleton(beanName, FactoryObject); FactoryObject是一个接口. 定义了一个钩子方法getObject(). 

    这个接口在这里这是进行了定义, 并不会执行. 什么时候执行呢? 后面调用的时候执行. 

    下面来看看getSingleton()方法, 钩子方法也是在这里被调用的.

     1 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
     2         Assert.notNull(beanName, "Bean name must not be null");
     3         synchronized (this.singletonObjects) {
     4             // 第一步: 从一级缓存中获取单例对象
     5             Object singletonObject = this.singletonObjects.get(beanName);
     6             if (singletonObject == null) {
     7                 if (this.singletonsCurrentlyInDestruction) {
     8                     throw new BeanCreationNotAllowedException(beanName,
     9                             "Singleton bean creation not allowed while singletons of this factory are in destruction " +
    10                             "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
    11                 }
    12                 if (logger.isDebugEnabled()) {
    13                     logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
    14                 }
    15                 // 第二步: 将bean添加到singletonsCurrentlyInCreation中, 表示bean正在创建
    16                 beforeSingletonCreation(beanName);
    17                 boolean newSingleton = false;
    18                 boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
    19                 if (recordSuppressedExceptions) {
    20                     this.suppressedExceptions = new LinkedHashSet<>();
    21                 }
    22                 try {
    23                     // 第三步: 这里调用getObject()钩子方法, 就会回调匿名函数, 调用singletonFactory的createBean()
    24                     singletonObject = singletonFactory.getObject();
    25                     newSingleton = true;
    26                 }
    27                 catch (IllegalStateException ex) {
    28                     // Has the singleton object implicitly appeared in the meantime ->
    29                     // if yes, proceed with it since the exception indicates that state.
    30                     singletonObject = this.singletonObjects.get(beanName);
    31                     if (singletonObject == null) {
    32                         throw ex;
    33                     }
    34                 }
    35                 catch (BeanCreationException ex) {
    36                     if (recordSuppressedExceptions) {
    37                         for (Exception suppressedException : this.suppressedExceptions) {
    38                             ex.addRelatedCause(suppressedException);
    39                         }
    40                     }
    41                     throw ex;
    42                 }
    43                 finally {
    44                     if (recordSuppressedExceptions) {
    45                         this.suppressedExceptions = null;
    46                     }
    47                     afterSingletonCreation(beanName);
    48                 }
    49                 if (newSingleton) {
    50                     addSingleton(beanName, singletonObject);
    51                 }
    52             }
    53             return singletonObject;
    54         }
    55     }

    这里是调用getBean().

    第一步: 去一级缓存中取成熟的单例bean. 如果拿到了, 就直接返回. 如果没拿到. 那么执行创建. 

    第二步: 在创建之前, 先把这个bean放入到正在创建的单例bean集合中. 标记这个bean正在创建中

    第三步: 就是调用钩子方法getObject()了. 这个方法的方法体是在上面定义的. 其内容是去创建实例

                sharedInstance = getSingleton(beanName, () -> {
                            try {
                                // 这里定义了一个钩子函数. 此时只是定义, 并不执行. 在真正需要创建bean的地方才会执行
                                return createBean(beanName, mbd, args);
                            }
                            catch (BeansException ex) {
                                // Explicitly remove instance from singleton cache: It might have been put there
                                // eagerly by the creation process, to allow for circular reference resolution.
                                // Also remove any beans that received a temporary reference to the bean.
                                destroySingleton(beanName);
                                throw ex;
                            }
                        });

    这里的代码逻辑是完成了创建之前的逻辑

    2.3 创建bean 

    下面看看创建bean的过程

      1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      2             throws BeanCreationException {
      3 
      4         // Instantiate the bean.
      5         BeanWrapper instanceWrapper = null;
      6         if (mbd.isSingleton()) {
      7             instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
      8         }
      9         if (instanceWrapper == null) {
     10             /**
     11              * 第一步: 实例化
     12              * 这里面的调用链非常深, 后面再看
     13              * bean实例化有两种方式
     14              * 1. 使用反射:  使用反射也有两种方式,
     15              *         a. 通过无参构造函数 (默认的方式)
     16              *             从beanDefinition中可以得到beanClass,
     17              *             ClassName = BeanDefinition.beanClass
     18              *             Class clazz = Class.forName(ClassName);
     19              *             clazz.newInstance();
     20              *             这样就可以实例化bean了
     21              *
     22              *         b. 通过有参函数.
     23              *            ClassName = BeanDefinition.beanClass
     24              *             Class clazz = Class.forName(ClassName);
     25              *             Constractor con = class.getConstractor(args....)
     26              *             con.newInstance();
     27              *
     28              * 2. 使用工厂
     29              *         我们使用@Bean的方式, 就是使用的工厂模式, 自己控制实例化过程
     30              *
     31              */
     32             instanceWrapper = createBeanInstance(beanName, mbd, args);
     33         }
     34         // 这里使用了装饰器的设计模式
     35         final Object bean = instanceWrapper.getWrappedInstance();
     36         Class<?> beanType = instanceWrapper.getWrappedClass();
     37         if (beanType != NullBean.class) {
     38             mbd.resolvedTargetType = beanType;
     39         }
     40 
     41         // Allow post-processors to modify the merged bean definition.
     42         // 允许后置处理器修改已经合并的beanDefinition
     43         synchronized (mbd.postProcessingLock) {
     44             if (!mbd.postProcessed) {
     45                 try {
     46                     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
     47                 }
     48                 catch (Throwable ex) {
     49                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     50                             "Post-processing of merged bean definition failed", ex);
     51                 }
     52                 mbd.postProcessed = true;
     53             }
     54         }
     55 
     56         /**
     57          * 缓存单例bean到三级缓存中, 以防止循环依赖
     58          * 判断是否是早期引用的bean, 如果是, 则允许提前暴露引用
     59      *
     60          * 判断是否能够早起暴露的条件
     61          *     1. 是单例
     62          *     2. 允许循环依赖
     63          *     3. 正在创建的bean
     64          */
     65         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
     66                 isSingletonCurrentlyInCreation(beanName));
     67         if (earlySingletonExposure) {
     68             if (logger.isTraceEnabled()) {
     69                 logger.trace("Eagerly caching bean '" + beanName +
     70                         "' to allow for resolving potential circular references");
     71             }
     72             // 把我们的早期对象包装成一个singletonFactory对象, 该对象提供了getObject()方法, 把静态的bean放到三级缓存中去了.
     73             addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
     74         }
     75 
     76         // Initialize the bean instance.
     77         Object exposedObject = bean;
     78         try {
     79             // 第二步:填充属性, 给属性赋值(调用set方法)  这里也是调用的后置处理器
     80             populateBean(beanName, mbd, instanceWrapper);
     81             // 第三步: 初始化.
     82             exposedObject = initializeBean(beanName, exposedObject, mbd);
     83         }
     84         catch (Throwable ex) {
     85             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
     86                 throw (BeanCreationException) ex;
     87             }
     88             else {
     89                 throw new BeanCreationException(
     90                         mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
     91             }
     92         }
     93 
     94         /**
     95          * 初始化完成以后, 判断是否是早期的对象
     96          * 是循环依赖. 才会走进这里来
     97           */
     98         if (earlySingletonExposure) {
     99             // 去缓存中获取到我们的对象 由于传递的allowEarlyReference是false, 要求只能在一级二级缓存中取
    100             // 正常的普通的bean(不存在循环依赖的bean) 创建的过程中, 不会把三级缓存提升到二级缓存中.
    101             Object earlySingletonReference = getSingleton(beanName, false);
    102             if (earlySingletonReference != null) {
    103                 if (exposedObject == bean) {
    104                     exposedObject = earlySingletonReference;
    105                 }
    106                 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
    107                     String[] dependentBeans = getDependentBeans(beanName);
    108                     Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
    109                     for (String dependentBean : dependentBeans) {
    110                         if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
    111                             actualDependentBeans.add(dependentBean);
    112                         }
    113                     }
    114                     if (!actualDependentBeans.isEmpty()) {
    115                         throw new BeanCurrentlyInCreationException(beanName,
    116                                 "Bean with name '" + beanName + "' has been injected into other beans [" +
    117                                 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
    118                                 "] in its raw version as part of a circular reference, but has eventually been " +
    119                                 "wrapped. This means that said other beans do not use the final version of the " +
    120                                 "bean. This is often the result of over-eager type matching - consider using " +
    121                                 "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
    122                     }
    123                 }
    124             }
    125         }
    126 
    127         // Register bean as disposable.
    128         try {
    129             registerDisposableBeanIfNecessary(beanName, bean, mbd);
    130         }
    131         catch (BeanDefinitionValidationException ex) {
    132             throw new BeanCreationException(
    133                     mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    134         }
    135 
    136         return exposedObject;
    137     }

    首先, 实例化bean, 实例化的方式有两种. 一种是通过反射, 另一种是通过动态

     1        /**
     2              * 第一步: 实例化
     3              * 这里面的调用链非常深, 后面再看
     4              * bean实例化有两种方式
     5              * 1. 使用反射:  使用反射也有两种方式,
     6              *         a. 通过无参构造函数 (默认的方式)
     7              *             从beanDefinition中可以得到beanClass,
     8              *             ClassName = BeanDefinition.beanClass
     9              *             Class clazz = Class.forName(ClassName);
    10              *             clazz.newInstance();
    11              *             这样就可以实例化bean了
    12              *
    13              *         b. 通过有参函数.
    14              *            ClassName = BeanDefinition.beanClass
    15              *             Class clazz = Class.forName(ClassName);
    16              *             Constractor con = class.getConstractor(args....)
    17              *             con.newInstance();
    18              *
    19              * 2. 使用工厂
    20              *         我们使用@Bean的方式, 就是使用的工厂模式, 自己控制实例化过程
    21              *
    22              */
    23             instanceWrapper = createBeanInstance(beanName, mbd, args);

    判断是否是早期暴露的bean. 满足早期暴露的bean的三个条件是

    1. 是单例的

    2. 允许循环依赖

    3. bean已经是处在正在创建中的行列了.

         /* 判断是否能够早起暴露的条件
             *     1. 是单例
             *     2. 允许循环依赖
             *     3. 正在创建的bean
             */
            boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                    isSingletonCurrentlyInCreation(beanName));    

    创建bean的第二步: 属性赋值

    // 第二步:填充属性, 给属性赋值(调用set方法)  这里也是调用的后置处理器
    populateBean(beanName, mbd, instanceWrapper);

    在这里会判断, 是否带有@Autowired的属性. 分为两种一种是Name,一种是Type

    @SuppressWarnings("deprecation")  // for postProcessPropertyValues
        protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
            if (bw == null) {
                if (mbd.hasPropertyValues()) {
                    throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
                }
                else {
                    // Skip property population phase for null instance.
                    return;
                }
            }
    
            // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
            // state of the bean before properties are set. This can be used, for example,
            // to support styles of field injection.
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            return;
                        }
                    }
                }
            }
    
            PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    
            // 判断属性是否有Autowired注解
            int resolvedAutowireMode = mbd.getResolvedAutowireMode();
            // Autowired是根据名字或者根据类型
            if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
                MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
                // Add property values based on autowire by name if applicable.
                if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
                    autowireByName(beanName, mbd, bw, newPvs);
                }
                // Add property values based on autowire by type if applicable.
                if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
                    autowireByType(beanName, mbd, bw, newPvs);
                }
                pvs = newPvs;
            }
    
            ......
        }

    如果按照名字注入

     1 protected void autowireByName(
     2             String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
     3 
     4         String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
     5         for (String propertyName : propertyNames) {
     6             if (containsBean(propertyName)) {
     7                 // 调用getBean
     8                 Object bean = getBean(propertyName);
     9                 pvs.add(propertyName, bean);
    10                 registerDependentBean(propertyName, beanName);
    11                 if (logger.isTraceEnabled()) {
    12                     logger.trace("Added autowiring by name from bean name '" + beanName +
    13                             "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
    14                 }
    15             }
    16             else {
    17                 if (logger.isTraceEnabled()) {
    18                     logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
    19                             "' by name: no matching bean found");
    20                 }
    21             }
    22         }
    23     }

    会再次调用getBean方法. 构建bean. 这是就有可能出现循环依赖了. 

    按类型注入也是一样的. 

    只是解析bean的方式不同.

    创建bean的第三步: 初始化

     // 第三步: 初始化.
     exposedObject = initializeBean(beanName, exposedObject, mbd);

    在初始化bean的时候, 会调用很多的aware. 还会调用init-method方法. 以及bean的后置处理器.

    第四步:删除实例化和静态方法在缓存中的数据

    /**
             * 初始化完成以后, 判断是否是早期的对象
             * 是循环依赖. 才会走进这里来
              */
            if (earlySingletonExposure) {
                // 去缓存中获取到我们的对象 由于传递的allowEarlyReference是false, 要求只能在一级二级缓存中取
                // 正常的普通的bean(不存在循环依赖的bean) 创建的过程中, 不会把三级缓存提升到二级缓存中.
                Object earlySingletonReference = getSingleton(beanName, false);
                if (earlySingletonReference != null) {
                    if (exposedObject == bean) {
                        exposedObject = earlySingletonReference;
                    }
                    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                        String[] dependentBeans = getDependentBeans(beanName);
                        Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                        for (String dependentBean : dependentBeans) {
                            if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                                actualDependentBeans.add(dependentBean);
                            }
                        }
                        if (!actualDependentBeans.isEmpty()) {
                            throw new BeanCurrentlyInCreationException(beanName,
                                    "Bean with name '" + beanName + "' has been injected into other beans [" +
                                    StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                    "] in its raw version as part of a circular reference, but has eventually been " +
                                    "wrapped. This means that said other beans do not use the final version of the " +
                                    "bean. This is often the result of over-eager type matching - consider using " +
                                    "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                        }
                    }
                }
            }
    removeSingletonIfCreatedForTypeCheckOnly调用方法, 删除缓存.

    这既是getBean()整个的过程. 中间还有很多细节, 没有往里面深入的看, 因为spring代码非常的深, 看的太深就忘了我们的目标了. 结合之前手写的spring循环依赖的思想看, 还是可以看得懂的. 

    三. 接下来有几个问题

    问题1: 为什么需要二级缓存和三级缓存?

    一级缓存: 用来存储完整的bean

    二级缓存: 用来存储早期的,纯净的bean, 也就是没有注入属性的bean

    三级缓存: 存的是函数的接口, 主要目的是为了解耦

     二级缓存 和三级缓存 结合起来, 解决了循环依赖下的AOP动态代理的问题

    问题2:有没有解决构造函数的循环依赖

    答案是没有. 因为构造函数是在实例化的时候构建的. 这个时候bean都还没有创建, 所以没有办法处理循环依赖.如果出现构造函数的循环依赖, 是会直接报错的..

    问题3:有没有解决多例下的循环依赖

    也是没有的, 因为我们会判断, 如果是多例, 那么会抛出异常

     1             /**
     2              * 第二步: 判断当前bean是否是正在创建中的多例bean, 如果是就抛出异常
     3              *
     4              * 2. 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
     5              * spring 只能解决单例对象的setter注入的循环依赖, 不能解决构造器注入
     6              *
     7              * 如果是多例的bean, 当前正在创建bean, 也会抛出异常---这也是循环依赖的问题
     8              */
     9             if (isPrototypeCurrentlyInCreation(beanName)) {
    10                 throw new BeanCurrentlyInCreationException(beanName);
    11             }   
  • 相关阅读:
    python之路_爬虫之selenium模块
    python之路_爬虫之requests模块补充
    扩展中国剩余定理讲解
    扩展中国剩余定理讲解
    bzoj3225 [Sdoi2008]立方体覆盖——扫描线
    差分约束讲解
    CF917C Pollywog —— 状压DP + 矩乘优化
    斜率优化讲解
    AC自动机讲解
    BZOJ2870—最长道路tree
  • 原文地址:https://www.cnblogs.com/ITPower/p/13956880.html
Copyright © 2011-2022 走看看