Spring是怎么解决Bean之间的循环依赖的?

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是怎么解决类似的循环引用问题的?


波斯汪
浏览 921回答 5
5回答

开满天机

循环依赖只会在构造器中产生,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"));    }}@Componentclass A{    @Autowired    public A(B b) {    }}@Componentclass B{    @Autowired    public B(A a) {    }}

慕的地8271018

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

守候你守候我

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,。。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java