Spring如何解决循环依赖

.什么是循坏依赖

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

在这里插入图片描述
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创建对象过程 如下图所示:
在这里插入图片描述
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注入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值