用@Autowired属性标记注入构造函数的目的是什么?

时间:2019-05-13 15:16:43

标签: spring dependency-injection dependencies

我正在尝试将@Autowired注释包裹起来。我已经读过了,但是对我来说仍然没有多大意义

我要寻找的特定情况是将存储库传递给微服务类

我们为什么这样做

@Autowired
public SomeClass (Repo repo) {
    this.repo = repo;
}

不是简单地做

public SomeClass (Repo repo) {
    this.repo = repo;
}

4 个答案:

答案 0 :(得分:1)

你是对的。像Spring一样,DI容器通过粘附到Dependency Inversion Principle(DIP)来使组件彼此相互分离。从这个角度来看,至少可以说,当您的DI容器强迫您将那些特定于库的属性应用于类时,这很尴尬。这又引入了紧密耦合,这是我们正在努力防止的事情。它还强制供应商锁定。现在,所有应用程序代码都依赖于此外部工具。这违反了DIP。

相反,当您的应用程序组件具有单个公共构造函数(即a good practice)时,就无需在类中定义任何此类属性。在这种情况下,类的构造函数会明确声明其所需的依赖关系。任何好的DI容器都应该能够基于该单个构造函数提供的静态类型信息来组成对象图。

如果我没记错的话,较新版本的Spring确实允许您省略该属性。

答案 1 :(得分:0)

当您有多个构造函数时,必须指出要使用的构造函数。很多时间都没用。

在这里检查:https://www.baeldung.com/constructor-injection-in-spring

  

从Spring 4.3开始,具有单个构造函数的类可以省略   @Autowired注释。有点方便和   删除样板!

答案 2 :(得分:0)

您可以这样做:

public SomeClass (Repo repo) {
    this.repo = repo;
}

如果您打算自己实例化对象。 但是,由于您希望容器实例化对象(bean),因此您指示容器在创建Repo bean的过程中注入SomeClass依赖项。您可以通过在构造函数的顶部添加@Autowired来实现。

您也可以执行此操作(现场注入):

@Component
public class SomeClass {
    @Autowired
    private Repo repo;
} 

但是为了简化单元测试,最好使用构造函数注入。 请注意,由于Spring 4.3 @Autowired在构造函数上不再是必需的。

编辑

更好的是,在使用Lombok时,您可以这样做:

@Component
@RequiredArgConstructor
public class SomeClass {

    private final Repo repo;
}

Lombok将生成构造函数

public SomeClass (Repo repo) {
    this.repo = repo;
}

为您和容器将注入依赖项。

答案 3 :(得分:0)

@Autowired批注将自动从应用程序上下文中使用Repo类型的'Bean'(由弹簧管理的资源),如果存在的话。如果您的SomeClass方法本身就是一个“ Bean”(用@ Component,@ Service或@Repository注释),则Spring将在实例化SomeClass bean之前确保应用程序上下文中存在Repo类型的bean。

这篇文章很有帮助:https://www.baeldung.com/spring-autowire

正如该线程上的其他人所提到的,构造函数注入使单元测试更加容易。解决此问题的一种方法是创建一个用@TestConfiguration注释的静态类,该类包含测试上下文所需的bean。

本文提供有关以下内容的信息:https://www.baeldung.com/spring-boot-testing

如果您不熟悉春季,Baeldung网站是一个很好的资源。