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

GJC*_*ode 8 java spring spring-boot

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

我有这样的服务:

@Service
public class MyService {

    public MyService() {
        // do something
    }

}
Run Code Online (Sandbox Code Playgroud)

在课堂上,我有:

public class MyClass {

    @Autowired
    MyService service;

}
Run Code Online (Sandbox Code Playgroud)

问题是:

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

mic*_*alk 8

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

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

但是,场注入通常不是一个好主意,因为您可能无法测试此类组件。构造器或setter注入是更好的选择。

如果您将其更改MyClass为:

public class MyClass {

    private MyService service;

    @Autowired
    public MyClass(MyService service) {
        this.service = service;
    }

}
Run Code Online (Sandbox Code Playgroud)

在这里,您提供了自己的构造函数-请注意,在这种情况下,不会生成任何默认构造函数。因此,Spring将必须调用您提供的构造函数并满足其依赖性。如果没有可以注入的依赖项,则将引发异常。

请注意,即使没有Spring也可以使用您的类:

MyService myService = new MyService();
MyClass myclass = new MyClass(myService);
Run Code Online (Sandbox Code Playgroud)

通过使用Spring构造型标记您的类并通过使用@Autowired,只需启用Spring对上下文创建和依赖项注入的支持(在自动包扫描的情况下)

  • 请注意,从 Spring 4.3 版本开始,构造函数上的 @Autowired 注解可以省略。 (2认同)

Mar*_*sic 6

由于MyService有一个@Service注解,Spring 会自动实例化它(即注册为 bean)。

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

由于它通过调用找到的无参数构造函数来创建服务,因此将执行位于“//do something”位置的代码。

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

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

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