小编典典

究竟什么是现场注入以及如何避免它?

all

我在一些关于 Spring MVC 和 Portlets 的文章中读到不推荐使用 字段注入。 据我了解, 字段注入 是当您注入一个 Bean
@Autowired

@Component
public class MyComponent {
    @Autowired
    private Cart cart;
}

在我的研究过程中,我还阅读了有关 构造函数注入 的内容:

@Component
public class MyComponent {
    private final Cart cart;

    @Autowired
    public MyComponent(Cart cart){
       this.cart = cart;
    }
}

这两种注射方式的优缺点是什么?



阅读 59

收藏
2022-05-23

共1个答案

小编典典

注射类型

如何将依赖项注入到 bean 中有三个选项:

  1. 通过构造函数
  2. 通过setter或其他方法
  3. 通过反射,直接进入字段

您正在使用选项 3。这就是您@Autowired直接在您的字段上使用时发生的情况。


注射指南

Spring 推荐的一般准则(参见基于Constructor-based
DI
Setter-based
DI
的部分)如下:

  • 对于强制依赖或以不变性为目标时,请使用构造函数注入
  • 对于可选或可变依赖项,使用 setter 注入
  • 在大多数情况下避免现场注入

现场注入的缺点

现场注入不被认可的原因如下:

  • 你不能像构造函数注入那样创建不可变对象
  • 你的类与你的 DI 容器紧密耦合,不能在它之外使用
  • 没有反射就无法实例化您的类(例如在单元测试中)。您需要 DI 容器来实例化它们,这使您的测试更像集成测试
  • 您真正的依赖项是从外部隐藏的,并且不会反映在您的界面中(构造函数或方法)
  • 拥有十个依赖项真的很容易。如果您使用构造函数注入,您将有一个带有十个参数的构造函数,这表明某些东西是可疑的。但是您可以无限期地使用字段注入来添加注入字段。有太多的依赖是一个危险信号,该类通常做不止一件事,并且可能违反单一责任原则。

结论

根据您的需要,您应该主要使用构造函数注入或构造函数和设置器注入的某种组合。现场注入有很多缺点,应该避免。字段注入的唯一优点是写起来更方便,并没有超过所有的缺点。


进一步阅读

我写了一篇关于为什么通常不建议使用字段注入的博客文章:Field Dependency Injection Considered
Harmful

2022-05-23