关于Spring循环依赖的面试题

情况1 set注入

图片说明
bean1

@Repository
public class Bean1 {
    private Bean2 bean2;
    public Bean1() {
        System.out.println("Bean1()");
    }
    public Bean1(Bean2 bean2) {
        System.out.println("Bean1(Bean2 bean2)"+bean2.getClass());
        this.bean2 = bean2;
    }
    @Autowired
    public void setBean2(Bean2 bean2) {
        System.out.println("setBean2()");
        this.bean2 = bean2;
    }
}

bean2

@Repository
public class Bean2 {
    private Bean1 bean1;

    public Bean2() {
        System.out.println("Bean2()");
    }

    public Bean2(Bean1 bean1) {
        System.out.println("Bean2(Bean1 bean1)"+bean1.getClass());
        this.bean1 = bean1;
    }

    @Autowired
    public void setBean1(Bean1 bean1) {
        System.out.println("setBean1()");
        this.bean1 = bean1;
    }


}

Test

@Test
    public void test() {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Bean1 bean1 = context.getBean("bean1", Bean1.class);
        Bean2 bean2 = context.getBean("bean2", Bean2.class);
    }

结果:
Bean1()
Bean2()
setBean1()
setBean2()
没有问题,Spring三级缓存会帮我们解决循环依赖问题。

情况2 构造函数注入

图片说明

bean1

@Repository
public class Bean1 {
    private Bean2 bean2;
    public Bean1(Bean2 bean2) {
        System.out.println("Bean1(Bean2 bean2)"+bean2.getClass());
        this.bean2 = bean2;
    }

}

bean2

@Repository
public class Bean2 {
    private Bean1 bean1;
    public Bean2(Bean1 bean1) {
        System.out.println("Bean2(Bean1 bean1)"+bean1.getClass());
        this.bean1 = bean1;
    }
}

结果报错:

Is there an unresolvable circular reference?是否存在无法解析的循环引用

解决@Lazy

public Bean1(@Lazy Bean2 bean2) {
        System.out.println("Bean1(Bean2 bean2)"+bean2.getClass());
        this.bean2 = bean2;
    }

public Bean2(@Lazy Bean1 bean1) {
        System.out.println("Bean2(Bean1 bean1)"+bean1.getClass());
        this.bean1 = bean1;
    }

运行结果:

Bean1(Bean2 bean2)class com.kuang.dao.Bean2$$EnhancerBySpringCGLIB$$9f101a2 
Bean2(Bean1 bean1)class com.kuang.dao.Bean1$$EnhancerBySpringCGLIB$$f65578ff

使用动态代理延迟bean创建

图片说明

情况3 bean1采用set注入,bean2采用构造器注入

@Repository
public class Bean1 {
    private Bean2 bean2;

    public Bean1() {
        System.out.println("Bean1()");
    }

    public Bean1( Bean2 bean2) {
        System.out.println("Bean1(Bean2 bean2)"+bean2.getClass());
        this.bean2 = bean2;
    }

    @Autowired
    public void setBean2(Bean2 bean2) {
        System.out.println("setBean2()");
        this.bean2 = bean2;
    }


}
@Repository
public class Bean2 {
    private Bean1 bean1;

    public Bean2( Bean1 bean1) {
        System.out.println("Bean2(Bean1 bean1)"+bean1.getClass());
        this.bean1 = bean1;
    }

    public Bean1 getBean1() {
        return bean1;
    }


}
@Test
    public void test() {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        Bean2 bean2 = context.getBean("bean2", Bean2.class);
        Bean1 bean1 = context.getBean("bean1", Bean1.class);
    }
}

结果:
Bean1()
Bean2(Bean1 bean1)class com.kuang.dao.Bean1
setBean2()

当循环依赖bean1采用set注入,bean2采用构造器注入时,Spring可以解决,无论bean1,bean2的创建顺序。

全部评论
感谢分享,太有用了
点赞 回复 分享
发布于 2022-10-09 17:23 山西

相关推荐

不愿透露姓名的神秘牛友
10-12 10:48
已编辑
秋招之苟:邻居家老哥19届双2硕大厂开发offer拿遍了,前几天向他请教秋招,他给我看他当年的简历,0实习实验室项目技术栈跟开发基本不沾边😂,我跟他说这个放在现在中厂简历都过不了
点赞 评论 收藏
分享
3 6 评论
分享
牛客网
牛客企业服务