Java 为什么Spring对待构造函数注入与setter/字段注入不同?
我在project中遇到了一个循环依赖的小问题,并发现在字段/设置器上使用Java 为什么Spring对待构造函数注入与setter/字段注入不同?,java,spring,Java,Spring,我在project中遇到了一个循环依赖的小问题,并发现在字段/设置器上使用@Autowired可以解决这个问题,而不是在构造函数上使用@Autowired。这种行为的结论是,Spring在字段/设置器注入的情况下注入代理,在构造函数注入的情况下注入实际bean 问题是: 这背后的原因是什么?为什么注入不同的实体 考虑一下简单的代码片段: @Component public static class A{ @Autowired B b; @Autow
@Autowired
可以解决这个问题,而不是在构造函数上使用@Autowired
。这种行为的结论是,Spring在字段/设置器注入的情况下注入代理,在构造函数注入的情况下注入实际bean
问题是:
这背后的原因是什么?为什么注入不同的实体
考虑一下简单的代码片段:
@Component
public static class A{
@Autowired B b;
@Autowired C c;
}
@Component
public static class B{
@Autowired B b;
@Autowired C c;
// public B(C c,B b) { // this would cause circular dep problem
// this.c=c;
// }
}
@Component
public static class C{
@Autowired A a;
@Autowired B b;
}
我想到的一个想法是,通过构造函数注入,您可以立即使用注入的实体,因此,作为预生成初始化的bean被注入,而不是代理,但另一方面,我可以在setter方法中做同样的事情,所以,当您使用构造函数注入时,构造函数中使用的所有bean都必须提前创建。如果您有循环依赖项,则无法创建它们,因为循环依赖项和spring抛出异常 当您使用setter/field注入时,注入的元素是在创建bean之后设置的,所以允许循环依赖
顺便说一句,如果您有循环依赖,请尝试重新设计您的应用程序,因为您的代码将更难维护。这是首选构造函数注入的原因之一。您证明了它是一个代理吗?这应该很容易做到:只需打印thing.getClass().getName()。我认为代理根本不重要。根据这一点,构造函数注入和setter注入是等价的,这是完全错误的。时期在构造函数注入中,预期参数是完全构造的,但当出现循环依赖时,这是不可能的。因此,他们决定干脆把它当作一个错误。在setter注入中,您知道当作为参数传递时,参数可能不会完全构造。@rghome可能不会,这只是我的结论。此外,我认为它是一个代理,因为它有空字段,是一个“增强”类。不管它是否是代理,行为都是确定的。我只是想知道背后的原因this@GiacomoAlzetta感谢您指出文档。有趣的是,有这么多知识是如此的丰富。听起来很合理,这里最重要的部分是注入发生的时间点——对于字段/设置器,所有注入都是在创建每个bean实例之后完成的,而对于ctor,这可能是不可能的。