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

 air12345 发布于 2022-10-27 14:39

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

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

    2022-10-28 14:23 回答
  • 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应该会以获取类的顺序先初始化对象,然后根据对象的属性再做赋值,这样就不会出现卡在对象相互引用上了。

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

    2022-10-28 14:28 回答
  • 循环依赖只会在构造器中产生,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) {
        }
    }
    2022-10-28 14:32 回答
  • 先创建基本的Bean,再依赖注入(DI)。这样就没什么问题,解释得通。
    比如顺序如下:

    1. new出A的实例,

    2. new出B的实例,

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

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

    2022-10-28 14:33 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有