关于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()