Java 使用@Autowired的构造函数调用如何工作?
我正在学习Spring Boot框架,我想了解Java 使用@Autowired的构造函数调用如何工作?,java,spring,spring-boot,Java,Spring,Spring Boot,我正在学习Spring Boot框架,我想了解@Autowired注释是如何工作的。我知道在Spring Boot中我们有一个上下文,在该上下文中有一些bean可以通过@Autowired注释相互连接,这是因为在Spring Boot中我们有依赖项注入,但是构造函数是如何调用的 我有这样的服务: @Service public class MyService { public MyService() { // do something } } 在一节课上,我
@Autowired
注释是如何工作的。我知道在Spring Boot中我们有一个上下文,在该上下文中有一些bean可以通过@Autowired
注释相互连接,这是因为在Spring Boot中我们有依赖项注入,但是构造函数是如何调用的
我有这样的服务:
@Service
public class MyService {
public MyService() {
// do something
}
}
在一节课上,我有:
public class MyClass {
@Autowired
MyService service;
}
问题是:
是调用了MyService的构造函数并执行了“do something”还是调用了空构造函数,因此我不能依赖执行“do something”的事实?TL;博士
创建bean时,Spring必须调用目标bean类包含的构造函数:
@Autowired
标记此构造函数)@Autowired
标记其中一个,或者使用配置类定义bean)MyClass
的实例时,它将调用MyClass
类的默认构造函数,然后通过反射设置它的依赖关系
然而,现场注入通常是一个坏主意,因为您在测试此类组件时可能会遇到问题。构造函数或setter注入是更好的选择
如果您将MyClass
更改为:
public class MyClass {
private MyService service;
@Autowired
public MyClass(MyService service) {
this.service = service;
}
}
这里您提供了自己的构造函数-注意,在这种情况下不会生成默认构造函数。所以Spring必须调用您提供的构造函数并满足它的依赖性。如果没有可以注入的依赖项,将抛出异常
请注意,即使没有Spring,您也可以使用您的类:
MyService myService = new MyService();
MyClass myclass = new MyClass(myService);
通过使用Spring原型标记您的类,并使用@Autowired
您只需启用Spring对上下文创建和依赖项注入的支持(在自动包扫描的情况下)因为MyService有一个@Service注释,Spring将自动实例化它(即将其注册为bean)
在创建它时,它扫描类的构造函数,发现定义了一个无参数构造函数,这是它将使用的唯一构造函数
由于它通过调用找到的no args构造函数来创建服务,因此将执行位于“//do something”位置的代码
另一方面,如果不添加此构造函数,MyService类将隐式定义一个空的非args构造函数,因此Spring将使用空构造函数。但是在您的例子中,您已经定义了一个显式构造函数(它覆盖了隐式的空no-args构造函数),因此Spring将其视为唯一可用的构造函数,并且没有歧义
长话短说->如果定义了一个构造函数,Spring将始终自动使用它来创建bean
附言:如果你使用@Autowired注释,你也可以有一个带参数的构造函数。在这种情况下,Spring将调用此构造函数来创建bean,并传递所需的参数(如果已声明此类bean可以自动连接到构造函数中)。长话短说
Spring将使用默认构造函数(无参数构造函数)来构造组件。
在你的例子中
@Service
public class MyService {
public MyService() {
// do something
}
}
将调用构造函数并调用//do something
但是,请记住,如果您在类中添加了非默认构造函数(带参数的构造函数),那么编译器将不会为您生成默认构造函数,在这种情况下,spring将无法实例化您的MyService
比如说
@Service
public class MyService {
public MyService(String var) {
// do something
}
}
将抛出异常
com.example.MyService
中构造函数的参数0需要一个类型为“java.lang.String
”的bean,但找不到该bean。您的问题实际上与Spring无关。您可以决定如何构造MyService
类。当您提供匹配的构造函数时,Spring将调用它,如果不能,则调用失败。Spring可以为一个类“发明”自己的构造函数并使用它。你试过调试或只是在构造函数中打印吗?@Tom我认为这是相关的,因为我有Spring注释和Spring上下文。@daniu,这是一个理论问题,我想检索更多的InfossSpring注释,Spring上下文并没有那么重要。Spring无法更改Java规则,因此您可以通过决定提供哪些构造函数来决定Spring如何创建bean。感谢您的回答,我知道它只是启用了支持,但我想学习如何使用Spring和Spring哲学:)请注意,从Spring 4.3版开始,可以省略构造函数上的Autowired annotation。“调用构造函数”应为“调用构造函数”