java - Spring是怎么解决Bean之间的循环依赖的?
高洛峰
高洛峰 2017-04-18 10:03:41
[Java讨论组]

Spring Bean的初始化是首先调用Bean的默认构造器,然后调用set方法对属性进行注入。

如果:
A包含属性B,B包含了属性A。

例子:

@Component
public class A {
    @Autowired
    private B b;

    public void aHello(){
        System.out.println("aHello!");
    }

    public void bothHello(){
        aHello();
        b.bHello();
    }
}
@Component
public class B {
    @Autowired
    private A a;

    public void bHello(){
        System.out.println("bHello!");
    }

}
public class HelloApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        A a = context.getBean(A.class);
        a.bothHello();
    }
}

输出:

aHello!
bHello!

A和B循环引用,程序正常运行。请问Spring是怎么解决类似的循环引用问题的?

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(5)
阿神

先创建基本的Bean,再依赖注入(DI)。这样就没什么问题,解释得通。
比如顺序如下:

  1. new出A的实例,

  2. new出B的实例,

  3. A Bean中的b字段赋值B的实例,

  4. B bean中的a字段赋值A的实例。

怪我咯

循环依赖只会在构造器中产生,spring会抛出UnsatisfiedDependencyException异常

ublic class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("Test.xml");


        System.out.println(context.getBean("a"));
        System.out.println(context.getBean("b"));
    }
}

@Component
class A{
    @Autowired
    public A(B b) {
    }
}

@Component
class B{
    @Autowired
    public B(A a) {
    }
}
ringa_lee

你遇到这种问题会怎么做?总有个先后吧。。。肯定是先把对象构造出来,在解决依赖问题啊。
你可以覆盖默认的构造器,在里面打断点,看看具体的执行顺序呀。

天蓬老师
public class A {
    private B b;

    public A(B b) {
        this.b = b;
    }

    public void say(){
        System.out.println("A");
    }
}

public class B {
    private A a;

    public B(A a) {
        this.a = a;
    }

    public void say(){
        System.out.println("A");
    }
}

肯定有先后顺序,你可以试试在构造方法中对对象赋值。这样spring就会卡在两个对象相互引用上。

如果只是在属性中引用,spring应该会以获取类的顺序先初始化对象,然后根据对象的属性再做赋值,这样就不会出现卡在对象相互引用上了。

天蓬老师
  • 楼上说的对:在容器启动的时候,会把bean实例都初始化好的,你可以试试这样的一种情形,你使用了@Autowired注入一个java bean,但是不配置<bean id="" class="">,你会发现容器在启动的时候会报错,所以说明了,即使是循环依赖的关系,也是:在容器启动的时候,就会初始化好java bean,。。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号