Spring中对于循环依赖(Circular dependencies)的处理

Spring框架最核心的特点就是控制反转和依赖注入。控制反转的意思就是将创建对象的动作(new Class())交给Spring容器处理。接下来就是依赖注入。当spring容器创建一个对象时。如果对象中存在一些需要赋值属性。它会自动帮我们将对应的属性的值注入进去。遮掩就能得到一个完整的对象实例。

今天主要讨论spring容器在依赖注入时。对循环依赖的处理。

  • 依赖注入的流程
    ① 使用描述所有 bean 的配置元数据创建和初始化。配置元数据可以通过 XML、Java 代码或注释指定。ApplicationContext

② 对于每个 bean,其依赖项以属性、构造函数参数或静态工厂方法的参数的形式表示(如果使用该依赖项而不是普通构造函数)。当实际创建 bean 时,这些依赖项将提供给 bean。

③ 每个属性或构造函数参数都是要设置的值的实际定义,或对容器中另一个 bean 的引用。

④ 作为值的每个属性或构造函数参数都将其指定的格式转换为该属性或构造函数参数的实际类型。默认情况下,Spring 可以将字符串格式提供的值转换为所有内置类型,如 int long String boolean 、、 等。

  • 依赖注入的方式
    ① 通过构造器进行依赖注入。这是目前推荐的方式
    ② 通过Setter方法进行依赖注入

在使用构造器的方式进行依赖注入时会发生循环依赖的问题,会抛出BeanCurrentlyInCreationException异常。先看一下异常发生的大致流程,如下:
在这里插入图片描述
测试一下:
BeanA和BeanB如下:

@Component
public class BeanA {
    private BeanB beanB;

    public BeanA(BeanB beanB) {
        this.beanB = beanB;
    }
}
@Component
public class BeanB {
    private BeanA beanA ;

    public BeanB(BeanA beanA) {
        this.beanA = beanA;
    }
}

测试代码:

  BeanFactory factory = new AnnotationConfigApplicationContext("com.dong.spring.circular");
  BeanA bean = factory.getBean(BeanA.class);
  System.out.println(bean);
  

结果:
在这里插入图片描述
官方给的解决方案是使用Setter方式注入解决循环依赖的问题,我来试验一下:

继续创建如下测试类:

@Component
public class BeanC {
    private BeanD d ;
    @Autowired
    public void setBeanD(BeanD beanD) {
        this.d = beanD;
    }

    @Override
    public String toString() {
        return "BeanC{" +
                "beanD=" + d.hashCode() +
                '}';
    }
}
@Component
public class BeanD {
    private BeanC c ;
    @Autowired
    public void setC(BeanC c) {
        this.c = c;
    }

    @Override
    public String toString() {
        return "ClassD{" +
                "c=" + c.hashCode() +
                '}';
    }
}

测试:

BeanFactory factory = new AnnotationConfigApplicationContext("com.dong.spring.circular");
BeanC bean = factory.getBean(BeanC.class);
System.out.println(bean);

输出结果:
BeanC{beanD=811760110}

可以看到,使用setter方式确实可以解决循环注入的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值