Java 如何解决Spring中的循环依赖关系
如何解决spring中的循环依赖关系。当我们有一个类a依赖于类B,而类B依赖于C时,那么如何使用spring解决java(基于注释的)中的这些问题呢Java 如何解决Spring中的循环依赖关系,java,spring,Java,Spring,如何解决spring中的循环依赖关系。当我们有一个类a依赖于类B,而类B依赖于C时,那么如何使用spring解决java(基于注释的)中的这些问题呢 我的问题是假设B类被注入到A类中 BeanA package test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class
我的问题是假设B类被注入到A类中 BeanA
package test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class BeanA {
@Autowired
BeanB b;
}
…A类注入C类中
而B就像
BeanB
package test;
import org.springframework.stereotype.Component;
@Component
public class BeanB {
}
这是我的测试:
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class RefTest {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring.xml");
BeanC c = ac.getBean(BeanC.class);
System.out.println("is c null? " + (c == null));
System.out.println("is c.a null? " + (c.a == null));
System.out.println("is c.a.b null? " + (c.a.b == null));
}
}
我的spring.xml几乎为空(只有组件扫描
存在):
结果是:
c是否为空?假的
c.a是空的吗?假的
c.a.b是否为空?假的
通常,若注入不起作用,这是因为bean不是使用Spring创建的,而是使用了new
操作符
如果您以不同方式使用问题,请使用其他详细信息更新您的问题
顺便说一句:我同意Ian Mc的观点,这不是循环依赖。首先让我声明循环依赖是不好的。不管你是否使用弹簧。你应该重构你的代码来摆脱它们 现在,问题的解决方案是:据我所知,只有在使用构造函数注入时,Spring才能处理循环依赖关系。因此,当您让spring通过属性或setter注入来注入此依赖项时,它应该可以工作。尝试在构造函数中使用注释,如下所示:
@Component
public class C {
private final A a;
@Autowired
public C(@Lazy final A a) {
this.a = a;
}
}
这使得您的A bean只有在实际需要时才初始化,而不是在应用程序启动时,当它还没有准备好时才初始化。Rajeev,您所解释的不是循环依赖关系。您必须创建A、B和C作为springbean,并让Spring管理相关的依赖项 需要明确的是,循环依赖是a依赖于B,B依赖于C,但C依赖于a。那么在这种情况下,首先创建什么呢?无法创建,因为尚未创建B。无法创建B,因为C尚未创建。你不能创建C,因为A还没有创建。所以春天停止了 在你的例子中:A依赖于B,B依赖于C。那么现在呢?Spring说:我将首先创建C。然后我将创建B,最后我将创建A 这是可能的,因为Spring将首先创建所有bean定义。然后,当创建bean时,Spring理解了连接,并以正确的顺序构建bean以解决依赖关系 我创建了一个小项目来模拟您的情况,包括您如何描述问题,以及稍后您在评论中的反应。没问题!Spring可以毫无问题地管理您描述的两种场景。我实现了InitialingBean来钩住创建,以显示bean的创建顺序
@Component
public class A implements InitializingBean {
@Autowired
private B b;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "My name is "+name+"; b name is "+b.getName();
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Creating A");
System.out.println("B name="+b.getName());
}
}
@Component
public class B implements InitializingBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "B [name=" + name + "]";
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Creating b");
}
}
@Component
public class C implements InitializingBean {
@Autowired
private A a;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "My name is "+name+"; a name is "+a.getName();
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Creating c");
System.out.println("A name="+a.getName());
}
}
将C定义为bean。。然后在B上自动连接(任何形式)C。。然后在A.上自动连线B。。当然,将B和A定义为bean,我不知道这是如何循环的?A依赖于B,B依赖于C是很自然的。请进一步解释,或者发布spring给出的错误。我的问题是,假设B类在A类中被注入,而A类在C类中被注入,那么A类如何没有被初始化就会产生问题。我希望使用initializingbean的解决方案是在PropertieSet()之后重写其方法的正确选项。@Rajeev请在问题中直接澄清,不要为此目的使用注释。通过Setter注入,Spring上可能存在循环依赖,您可以在该链接中看到
@Component
public class A implements InitializingBean {
@Autowired
private B b;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "My name is "+name+"; b name is "+b.getName();
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Creating A");
System.out.println("B name="+b.getName());
}
}
@Component
public class B implements InitializingBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "B [name=" + name + "]";
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Creating b");
}
}
@Component
public class C implements InitializingBean {
@Autowired
private A a;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "My name is "+name+"; a name is "+a.getName();
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Creating c");
System.out.println("A name="+a.getName());
}
}