@Autowired的构造函数调用如何工作?

时间:2019-05-11 09:12:55

标签: java spring spring-boot

我正在学习Spring Boot框架,并且想了解@Autowired批注的工作方式。我知道在Spring Boot中我们有一个上下文,并且在该上下文中有可以通过@Autowired批注相互连接的bean,这是因为在Spring Boot中我们具有依赖项注入,但是构造函数是如何调用的?

我有这样的服务

@Service
public class MyService {

public MyService() {
   // do something
}
}

在课堂上,我有:

public MyClass {

@Autowired 
MyService service;
}

问题是:是调用MyService的构造函数并执行“做某事”,还是将其调用为空的构造函数,因此我不能依靠将执行“做某事”的事实吗?

3 个答案:

答案 0 :(得分:7)

Spring IOC container(应用程序上下文)负责保存bean,并在需要时返回它们。要创建上下文,您必须告诉Spring在哪里寻找bean定义:您可以提供xml文件,java配置或启用给定程序包中组件的自动扫描。当创建Spring上下文时,它必须创建bean。它将尝试调用构造函数,并为需要它们的bean提供任何依赖关系。

在您的示例中,将为上下文创建MyClass的实例时,它将调用MyClass类的默认构造函数,然后通过反射设置其依赖性。

但是,场注入通常不是一个好主意,因为您在测试此类组件时可能会遇到问题。构造函数或二传手注入是更好的选择。

如果您将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对上下文创建和依赖注入的支持(在自动包扫描的情况下)

答案 1 :(得分:1)

由于MyService具有 @Service 批注,因此Spring会自动将其实例化(即,将其注册为bean)。

在创建它时,它扫描类的构造函数,并看到定义了无参数的构造函数,这是唯一的构造函数,因此它将使用它。 / p>

由于它通过调用找到的no-args构造函数来创建服务,因此将执行代码中“ //做某事”位置的代码。

另一方面,如果您没有添加此构造函数,则 MyService 类将隐式定义一个空的非参数构造函数,因此在这种情况下,Spring将采用该空构造函数。但在您的情况下,您定义了一个构造函数(该构造函数将覆盖隐式的空无参数构造函数),因此它将其视为唯一可用的构造函数,并且没有歧义。

长话短说->如果定义了一个构造函数,Spring将始终自动使用它来创建bean。

PS:如果使用@Autowired批注,则还可以具有带有参数的构造函数,在这种情况下,如果声明了可以自动装配到其中的Bean,则Spring将调用此构造函数来创建Bean并传递所需的参数。构造函数。

答案 2 :(得分:-1)

长话短说

Spring将使用默认构造函数(no-args构造函数)来构造组件。 在您的示例中

@Service
public class MyService {

public MyService() {
   // do something
}
}

将调用构造函数,并调用// do something

但是,请记住,如果您向类(带有参数的构造函数)添加了非默认构造函数,则编译器将不会为您生成默认构造函数,在这种情况下,spring将无法实例化您的{{ 1}}

例如

MyService

将引发异常 @Service public class MyService { public MyService(String var) { // do something } } 中构造函数的参数0需要找不到类型为'com.example.MyService'的bean。