美文网首页
spring 如何解决循环依赖的问题

spring 如何解决循环依赖的问题

作者: Jaypc | 来源:发表于2020-10-30 09:19 被阅读0次

1.什么是循坏依赖

即循环引用,两个或多个bean相互引用,最终形成一个环。如图:


image.png

2.什么是循环调用

循环调用是方法之间的环调用。循环调用无法解决,除非有终结条件,否则就是死循环,最终导致内存溢出错误。

3.构造器循环依赖

3.1 循环依赖过程

  Class A{
        private B b;
        A(B b){
              this.b = b;
         }
   }

   Class B{
          private C c;
          B(C c){
              this.c = c;
          }
   }

   Class C{
          private A a;
          C(A a){
                this.a = a;
           }
    }

JVM创建对象过程 如下图所示:


image.png

3.2 Spring解决构造器循环依赖
 无法解决通过构造器注入构成的循环依赖,只能抛出BeanCurrentylyInCreationException异常表示循环依赖。
 Spring容器将每一个正在创建的bean标识符放在一个“当前创建bean池”中,bean表示符在创建过程中将一直保持在这个池中,因此,如果在创建bean过程中发现自己已经在“当前创建bean池”中,将抛出BeanCurrentylyInCreationException异常,表示循环依赖;对于创建完毕的bean,将从“当前创建bean池”中清除掉。

4.setter循环依赖
 通过Spring容器提前暴露刚完成构造器注入但未完成其他步骤(如setter注入)的bean来完成的。通过提前暴露一个单例工厂方法,从而使其他bean能够引用到该bean。
 注:只能解决单例作用域的bean循环依赖。
 具体步骤:
 (1)Spring容器创建单例 a bean,首先根据无参构造器创建bean,并暴露一个“ObjectFactory”,用于返回一个提前暴露一个创建中的bean,并将 “a”标识符放到“当前创建bean池”,然后进行setter注入b;
 (2)Spring容器创建单例 b bean,首先根据无参构造器创建bean,并暴露一个“ObjectFactory”,用于返回一个提前暴露一个创建中的bean,并将 “b”标识符放到“当前创建bean池”,然后进行setter注入c;
 (3)Spring容器创建单例 c bean,首先根据无参构造器创建bean,并暴露一个“ObjectFactory”,用于返回一个提前暴露一个创建中的bean,并将 “c”标识符放到“当前创建bean池”,然后进行setter注入a;进行注入"a"时,由于提前暴露了“ObjectFactory”工厂,从而使用它返回提前暴露一个创建中的bean。
 (4)最后在依赖注入“b”和“a”,完成setter注入。

https://www.jianshu.com/p/8bb67ca11831

https://www.jianshu.com/p/4463b9b81249

相关文章

网友评论

      本文标题:spring 如何解决循环依赖的问题

      本文链接:https://www.haomeiwen.com/subject/pldqvktx.html