3.2spring源码系列----循环依赖源码分析 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖

前端之家收集整理的这篇文章主要介绍了3.2spring源码系列----循环依赖源码分析 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

首先,我们在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<>(.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                  (isfactorybean(beanName)) {
22                     Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
23                      (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());
3435                          (isEagerInit) {
36                              获取bean
37                             getBean(beanName);
3839                     }
40                 }
41                  {
              // 第二步: 调用bean定义
42                     getBean(beanName);
4344             }
45         }
46 
47          Trigger post-initialization callback for all applicable beans...
48         
51         52              从缓存中得到实例instance
53             Object singletonInstance = getSingleton(beanName);
54              (singletonInstance instanceof SmartInitializingSingleton) {
55                 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
56                 null) {
57                     AccessController.doPrivileged((PrivilegedAction<Object>) () ->58                         smartSingleton.afterSingletonsInstantiated();
59                         return ;
60                     },getAccessControlContext());
6162                 63                     smartSingleton.afterSingletonsInstantiated();
64656667     }

 

首先,循环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,1)">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 
   Eagerly check singleton cache for manually registered singletons.
  9         // 第二步: 尝试去缓存中获取对象,如果没有获取到就创建bean
 10         Object sharedInstance = getSingleton(beanName);
 if (sharedInstance != null && args == ) {
 12             13                 判断当前类是否是正在创建中
 14                  (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                  {
 19                     logger.trace(Returning cached instance of singleton bean '" + beanName + '2021             }
 22             bean = getObjectForBeanInstance(sharedInstance,name,beanName,2324 
 25         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              (isPrototypeCurrentlyInCreation(beanName)) {
 37                 throw new BeanCurrentlyInCreationException(beanName);
 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                  (parentbeanfactory instanceof Abstractbeanfactory) {
 49                     return ((Abstractbeanfactory) parentbeanfactory).doGetBean(
 50                             nameToLookup,requiredType,args,typeCheckOnly);
 5152                 else if (args != 53                      Delegation to parent with explicit args.
 54                      (T) parentbeanfactory.getBean(nameToLookup,args);
 55if (requiredType != 57                      No args -> delegate to standard getBean method.
 58                      parentbeanfactory.getBean(nameToLookup,requiredType);
 5960                 61                      (T) parentbeanfactory.getBean(nameToLookup);
 6264 
 65             *
 66              * 方法参数typeCheckOnly是用来判断#getBean()方法时,表示是否为仅仅进行类型检查,67              * 如果不仅仅做类型检查,而是创建bean对象,则需要调用#markBeanAsCreated(String name)
 68              *
 69              70             if (!typeCheckOnly) {
 71                 markBeanAsCreated(beanName);
 7273 
 74             try75                 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
 76                 checkMergedBeanDefinition(mbd,1)">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 != 85                      (String dep : dependsOn) {
 86                          (isDependent(beanName,dep)) {
 87                              BeanCreationException(mbd.getResourceDescription(),1)">88                                     Circular depends-on relationship between '' and '" + dep + 89                         }
 90                         registerDependentBean(dep,beanName);
 91                         92                             getBean(dep);
 9394                         catch (NoSuchBeanDefinitionException ex) {
 95                             96                                     ' depends on missing bean ',ex);
 9798                     }
 99100 
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                         112                              createBean(beanName,mbd,args);
113114                          (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;
120121                     });
122                      得到bean实例对象
123                     bean = getObjectForBeanInstance(sharedInstance,mbd);
124125 
126                 if (mbd.isPrototype()) {  处理多例bean
127                      It's a prototype -> create a new instance.
128                     Object prototypeInstance = 129                     130                          当前正在创建多例bean
131                         beforePrototypeCreation(beanName);
132                          执行创建bean
133                         prototypeInstance =134135                     finally136                         afterPrototypeCreation(beanName);
137138                      获取bean实例对象
139                     bean = getObjectForBeanInstance(prototypeInstance,1)">140141 
142                 else {  处理其他类型的bean
143                     String scopeName = mbd.getScope();
144                     final Scope scope = this.scopes.get(scopeName);
145                     if (scope == 146                         new IllegalStateException(No Scope registered for scope name '" + scopeName + );
147148                     149                         Object scopedInstance = scope.get(beanName,1)">150                             beforePrototypeCreation(beanName);
151                             152                                 153                             }
154                             155                                 afterPrototypeCreation(beanName);
156157                         });
158                         bean = getObjectForBeanInstance(scopedInstance,1)">159160                      (IllegalStateException ex) {
161                          BeanCreationException(beanName,1)">162                                 Scope '' 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 singleton164                                 ex);
165166167168             169                 cleanupAfterBeanCreationFailure(beanName);
170                 171172         } 

 

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

 Object sharedInstance = getSingleton(beanName);

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

    if (sharedInstance != null && args == null) {
             (logger.isTraceEnabled()) {
                判断当前bean是否是正在创建中(单例bean)
                 (isSingletonCurrentlyInCreation(beanName)) {
                    logger.trace(" + beanName +
                            );
                }
                 {
                    logger.trace();
                }
            }
            bean = getObjectForBeanInstance(sharedInstance,null);
        }

 

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

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

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

  对应的代码是这一句

  

*
 29              * 判断当前的bean是不是多例,如果是这抛出异常
 30              *
 31              * 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
 32              * spring 只能解决单例对象的setter注入的循环依赖,1)">38             }

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

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

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

  第三种. 其他类型

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

if (mbd.isSingleton()) {  处理单例bean
mbd.isPrototype()) {  处理多例bean
else {  处理其他类型的bean
166                 }

 

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

if (mbd.isSingleton()) { // 处理单例bean
110                     sharedInstance = getSingleton(beanName,() -> {
111                         try {
112                             return createBean(beanName,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                         }
                     });
123                     bean =124                 }

 

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

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

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

 public Object getSingleton(String beanName,ObjectFactory<?> singletonFactory) {
 2         Assert.notNull(beanName,Bean name must not be null3         synchronized (.singletonObjects) {
 4             // 第一步: 从一级缓存中获取单例对象
 5             Object singletonObject = this.singletonObjects.(beanName);
 6             if (singletonObject == 7                 .singletonsCurrentlyInDestruction) {
 8                      BeanCreationNotAllowedException(beanName,1)">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!)1112                  (logger.isDebugEnabled()) {
13                     logger.debug(Creating shared instance of singleton bean '1415                 // 第二步: 将bean添加到singletonsCurrentlyInCreation中,表示bean正在创建
16                 beforeSingletonCreation(beanName);
17                 boolean newSingleton = false18                 boolean recordSuppressedExceptions = (this.suppressedExceptions == 19                  (recordSuppressedExceptions) {
20                     this.suppressedExceptions = new LinkedHashSet<>();
22                 23                     // 第三步: 这里调用getObject()钩子方法,就会回调匿名函数,调用singletonFactory的createBean()
24                     singletonObject = singletonFactory.getObject();
25                     newSingleton = true2627                 28                      Has the singleton object implicitly appeared in the meantime ->
29                      if yes,proceed with it since the exception indicates that state.
30                     singletonObject = (beanName);
31                     32                         3335                  (BeanCreationException ex) {
36                     37                         for (Exception suppressedException : .suppressedExceptions) {
                             ex.addRelatedCause(suppressedException);
41                     43                 44                     45                         4647                     afterSingletonCreation(beanName);
4849                  (newSingleton) {
                     addSingleton(beanName,singletonObject);
5253              singletonObject;
5455     }

 

这里是调用getBean().

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

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

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

            sharedInstance = getSingleton(beanName,1)"> {
                         {
                            // 这里定义了一个钩子函数. 此时只是定义,并不执行. 在真正需要创建bean的地方才会执行
                            return createBean(beanName,args);
                        }
                         (BeansException ex) {
                             Explicitly remove instance from singleton cache: It might have been put there
                             Also remove any beans that received a temporary reference to the bean.
                            destroySingleton(beanName);
                             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 = ;
  6          (mbd.isSingleton()) {
  7             instanceWrapper = .factorybeanInstanceCache.remove(beanName);
  8         }
  9         if (instanceWrapper == ) {
 10             *
 11              * 第一步: 实例化
 12              * 这里面的调用链非常深,后面再看
 13              * bean实例化有两种方式
 14              * 1. 使用反射:  使用反射也有两种方式, 15              *         a. 通过无参构造函数 (默认的方式)
 16              *             从beanDefinition中可以得到beanClass,1)"> 17              *             ClassName = BeanDefinition.beanClass
 18              *             Class clazz = Class.forName(ClassName);
 19              *             clazz.newInstance();
 20              *             这样就可以实例化bean了
 21              *
 22              *         b. 通过有参函数.
 23              *            ClassName = BeanDefinition.beanClass
 24  25              *             Constractor con = class.getConstractor(args....)
 26              *             con.newInstance();
 27  28              * 2. 使用工厂
 29              *         我们使用@Bean的方式,就是使用的工厂模式,自己控制实例化过程
 30  31              */
 32             instanceWrapper = createBeanInstance(beanName,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             mbd.postProcessed) {
 45                  {
 46                     applyMergedBeanDefinitionPostProcessors(mbd,beanType,beanName);
 47                 }
 48                  (Throwable ex) {
 49                      50                             Post-processing of merged bean definition Failed 51  52                 mbd.postProcessed =  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          (earlySingletonExposure) {
 68              (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,1)"> getEarlyBeanReference(beanName,bean));
 74  75 
 76          Initialize the bean instance.
 77         Object exposedObject = bean;
 78          79              第二步:填充属性,给属性赋值(调用set方法)  这里也是调用的后置处理器
 80             populateBean(beanName,instanceWrapper);
 81             // 第三步: 初始化.
 82             exposedObject = initializeBean(beanName,exposedObject,mbd);
 83  84          85             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
 86                  (BeanCreationException) ex;
 87  88              89                  BeanCreationException(
 90                         mbd.getResourceDescription(),1)">Initialization of bean Failed 91  92  93 
 94          95          * 初始化完成以后,判断是否是早期的对象
 96          * 是循环依赖. 才会走进这里来
 97            98          99              去缓存中获取到我们的对象 由于传递的allowEarlyReference是false,要求只能在一级二级缓存中取
100              正常的普通的bean(不存在循环依赖的bean) 创建的过程中,不会把三级缓存提升到二级缓存中.
101             Object earlySingletonReference = getSingleton(beanName,1)">102             if (earlySingletonReference != 103                 if (exposedObject == bean) {
104                     exposedObject = earlySingletonReference;
105 106                 this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
107                     String[] dependentBeans = getDependentBeans(beanName);
108                     Set<String> actualDependentBeans = (dependentBeans.length);
109                      (String dependentBean : dependentBeans) {
110                         removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
111                             actualDependentBeans.add(dependentBean);
112                         }
113                     }
114                     actualDependentBeans.isEmpty()) {
115                          BeanCurrentlyInCreationException(beanName,1)">116                                 Bean with name '' 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         129             registerDisposableBeanIfNecessary(beanName,bean,1)">130 131          (BeanDefinitionValidationException ex) {
132             133                     mbd.getResourceDescription(),1)">Invalid destruction signature134 135 
136          exposedObject;
137     }

 

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

 1         2  3  4  5              * 1. 使用反射:  使用反射也有两种方式,1)"> 6  7  8  9 10 11 12 13 14 15 16 17 18 19              * 2. 使用工厂
20 21 22              23             instanceWrapper = createBeanInstance(beanName,args);

 

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

1. 是单例的

2. 允许循环依赖

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

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

 

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

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

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

@SuppressWarnings(deprecation")   for postProcessPropertyValues
    protected  populateBean(String beanName,RootBeanDefinition mbd,@Nullable BeanWrapper bw) {
        if (bw == ) {
             (mbd.hasPropertyValues()) {
                 BeanCreationException(
                        mbd.getResourceDescription(),1)">Cannot apply property values to null instance);
            }
             {
                 Skip property population phase for null instance.
                ;
            }
        }

         Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
         state of the bean before properties are set. This can be used,for example,1)"> to support styles of field injection.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
             (BeanPostProcessor bp : getBeanPostProcessors()) {
                 (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),beanName)) {
                        ;
                    }
                }
            }
        }

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

         判断属性是否有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,bw,newPvs);
            }
            // Add property values based on autowire by type if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName,newPvs);
            }
            pvs = newPvs;
        }

        ......
    }

 

如果按照名字注入

 1  autowireByName(
            String beanName,AbstractBeanDefinition mbd,BeanWrapper bw,MutablePropertyValues pvs) {
 3 
 4         String[] propertyNames = unsatisfiedNonSimpleProperties(mbd,bw);
 5          (String propertyName : propertyNames) {
 6              (containsBean(propertyName)) {
 7                 // 调用getBean
 8                 Object bean = getBean(propertyName);
                pvs.add(propertyName,bean);
                registerDependentBean(propertyName,1)">11                 12                     logger.trace(Added autowiring by name from bean name '13                             ' via property '" + propertyName + ' to bean named '17                 18                     logger.trace(Not autowiring property '' of bean '19                             ' by name: no matching bean found22 23     }

 

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

按类型注入也是一样的. 

只是解析bean的方式不同.

 

创建bean的第三步: 初始化

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

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

 

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

*
         * 初始化完成以后,判断是否是早期的对象
         * 是循环依赖. 才会走进这里来
          */
         (earlySingletonExposure) {
            
            Object earlySingletonReference = getSingleton(beanName,1)">);
            ) {
                 bean) {
                    exposedObject = earlySingletonReference;
                }
                 hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = (dependentBeans.length);
                     (String dependentBean : dependentBeans) {
                        removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    actualDependentBeans.isEmpty()) {
                        " +
                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                " +
                                );
                    }
                }
            }
        }

 

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,也会抛出异常---这也是循环依赖的问题
 8              */
 9              (isPrototypeCurrentlyInCreation(beanName)) {
10                  BeanCurrentlyInCreationException(beanName);
11             }   

 

猜你在找的Spring相关文章