Spring在构造函数中注入依赖项而没有@Autowired批注

时间:2016-12-12 00:37:03

标签: spring spring-boot dependency-injection autowired

我正在试验这个官方的Spring tutorials中的示例,并且依赖于此代码:
https://github.com/spring-guides/gs-async-method/tree/master/complete

如果查看 AppRunner.java 类的代码,我有两个问题:

1)当服务器启动时,如果我在这个类的构造函数中放置一个断点,就好像在构造函数中, GitHubLookupService 是由spring提供的,使用 @Service 已配置的bean。但是,构造函数上没有@Autowired注释,那么在世界中如何使用正确的依赖项调用此构造函数?应该是null

Spring Boot 的自动假设吗? Spring是否看到“私有字段+构造函数参数,它假设它应该寻找合适的bean?” 是 Spring Framework 还是 Spring boot
我错过了什么吗?

2)我记得,向bean / service等提供默认构造函数是可以的。为什么这个类(AppRunner)没有默认的构造函数? Spring如何知道它应该使用参数运行构造函数? 是因为它是唯一的构造函数吗?

2 个答案:

答案 0 :(得分:85)

从Spring 4.3 开始,如果一个配置为Spring bean的类只有一个构造函数,则Autowired注释可以省略,Spring将使用该构造函数并注入所有必要的依赖。

关于默认构造函数:您需要默认构造函数,具有Autowired注释的构造函数(如果您有多个构造函数),或者只有一个构造函数在您的类中有或没有{ {1}}注释。

阅读官方Spring文档中的"@Autowired"章节以获取更多信息。

答案 1 :(得分:0)

这样想...假设您有以下组件:

@Component 
public class FooService {
    public FooService(Bar bar) { /*whatever*/ }
}

当 Spring 扫描这个类时,它想知道它应该如何构造一个实例。它使用反射,因此它可以在运行时获取所有构造函数的列表。

在这种情况下,Spring 必须如何构造这个实例是完全明确的。只有一个构造函数,因此无需做出决定,也完全没有歧义。

如果您在此处添加 @Autowired,则不会缩小任何范围,也不会向 Spring 提供任何额外信息来帮助其做出决定 - 因为只有一个候选人,所以它已经做出了决定。

因此,为了方便起见,Spring 团队决定 @Autowired 应该是可选的。由于它没有帮助 Spring 框架做出决定,因此它的存在只是噪音。

如果您的组件有多个构造函数,那么您可以在其中之一上使用 @Autowired 来告诉 Spring“使用这个,而不是那个”。