01
什么是循环依赖

Spring容器循环依赖包括构造器循环依赖和setter循环依赖
// 定义ClassA类public class ClassA {private ClassB classB;public ClassA(ClassB classB) {this.classB = classB;}}
//定义ClassB类public class ClassB {private ClassA classA;public ClassB(ClassA classA) {this.classA = classA;}}
@Configurationpublic class Config {@Beanpublic ClassA classA(ClassB classB){return new ClassA(classB);}@Beanpublic ClassB classB(ClassA classA){return new ClassB(classA);}}
public class Test {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);}}

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'classA': Requested bean is currently in creation: Is there an unresolvable circular reference?
创建名为“classA”的 bean 时出错:当前正在创建请求的 bean:是否存在无法解析的循环引用?
@Configurationpublic class Config {@Beanpublic ClassA classA(@Lazy ClassB classB) {return new ClassA(classB);}@Beanpublic ClassB classB(ClassA classA) {return new ClassB(classA);}}
最流行的解决方法之一,也是Spring 文档提出的,是使用 setter 注入。
简单地说,如果你更改 bean 的连接方式以使用 setter 注入(或字段注入)而不是构造函数注入 - 这确实解决了问题。通过这种方式,Spring 创建了 bean,但在需要它们之前不会注入依赖项。(将ClassA、ClassB改成Setter方式,代码如下)
public class ClassA {private ClassB classB;@Autowiredpublic void setClassB(ClassB classB) {this.classB = classB;}public ClassB getClassB() {return classB;}}public class ClassB {private ClassA classA;private String message = "Hi!";@Autowiredpublic void setClassA(ClassA classA) {this.classA = classA;}public String getMessage() {return message;}}
配置类稍作修改:
@Configurationpublic class Config {@Beanpublic ClassA classA() {return new ClassA();}@Beanpublic ClassB classB() {return new ClassB();}}
public class Test {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);ClassA classA = applicationContext.getBean(ClassA.class);Assert.assertEquals("Hi!",classA.getClassB().getMessage());}}
注:断言的目的是确认是否正确注入,检查其消息属性的值。Setter循环依赖并不会报错
文章转载自程序员舒克,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




