分析一个Spring循环引用失败的问题

本文通过一个例子深入分析了Spring在处理循环引用时的机制,解释了为何Spring无法解决"A的构造方法依赖B,B依赖A"的问题。在构造函数中存在循环引用时,Spring会在填充属性过程中遇到死锁,最终抛出异常。
摘要由CSDN通过智能技术生成

前言:

之前我们有分析过Spring是怎么解决循环引用的问题,主要思路就是三级缓存;Spring在加载beanA的时候会先调用默认的空构造函数(在没有指定构造函数实例化的前提下)得到一个空的实例引用对象,这个时候没有设置任何值,但是Spring会用缓存把它给提前暴露出来,让其他依赖beanA的bean可以持有它提前暴露的引用;比如 a 依赖b ,b依赖a,并且他们都是通过默认方法实例化,那么简单流程是这样的:

  1. ioc实例化a,a提前暴露自己的,然后填充属性值,在填充属性值的时候发现有个对象b,这个时候去容器里面取到b的引用,发现b还没有被创建,那么就走实例化b的流程;
  2. 实例化b;流程跟a一样;但是不同的是b填充属性的时候,发现有引用a的实例,这个时候a已经提前暴露了自己了,所以b可以直接在容器里面拿到a的引用;那么b就实例化并且也初始化完成了;
  3. 拿到b了之后,a就可以持有b的引用 ,整个流程就走完了;

Spring不能解决“A的构造方法中依赖了B的实例对象,同时B依赖了A的实例对象”这类问题

这篇文章我想从源码的角度来分析一下整个流程;并且分析一下Spring为什么不能解决“A的构造方法中依赖了B的实例对象,同时B依赖了A的实例对象”这类问题

例子

首先创建两个bean类; CirculationA 有个属性circulationB,并且有个构造函数给circulationB赋值;

public class CirculationA {

    private CirculationB circulationB;

    public CirculationA(CirculationB circulationB) {
        this.circulationB = circulationB;
    }
}
复制代码

CirculationB有个属性circulationA,然后set方法

public class CirculationB {
    private CirculationA circulationA;

    public CirculationA getCirculationA() {
        return circulationA;
    }

    public void setCirculationA(CirculationA circulationA) {
        this.circulationA = circulationA;
    }
}
复制代码

SpringContextConfig.xmlcirculationa 用给定的构造函数实例化; circulationb 就用默认的实例化方法(默认的空构造函数)

<bean id="circulationa" class="src.bean.CirculationA">
    <constructor-arg name="circulationB" ref="circulationb"/>
  </bean>
  <bean id="circulationb" class="src.bean.CirculationB" >
    <property name="circulationA" ref="circulationa"/>
  </bean>
复制代码

好,例子准完毕,上面的例子是 circulationa的构造函数里面有circulationb;然后circulationb属性里面有circulationa; 启动容器!结果如下:

警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'circulationa' defined in class path resource [config.xml]: Cannot resolve reference to bean 'circulationb' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'circulationb' defined in class path resource [config.xml]: Cannot resolve reference to bean 'circulationa' while setting bean property 'circulationA'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'circulationa': Requested bean is currently in creation: Is there an unresolvable circular reference?
Exception in thread "main" org.springframework.beans.factory.BeanCreationException
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值