Spring 简明教程
Spring - Dependency Injection
每个基于 Java 的应用程序都有一些对象可以协同工作,以展示最终用户所看到的工作应用程序。在编写复杂的 Java 应用程序时,应用程序类应尽可能独立于其他 Java 类,以增加重用这些类并使其独立于其他类进行单元测试的可能性。依赖注入(或有时称为连接)有助于将这些类粘合在一起,同时又保持它们独立性。
考虑您有一个包含文本编辑器组件的应用程序,并且您希望提供拼写检查。您的标准代码将如下所示 −
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor() {
spellChecker = new SpellChecker();
}
}
我们在此处所做的是创建 TextEditor 和 SpellChecker 之间的依赖关系。在控制反转场景中,我们改为执行类似以下操作 −
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
}
在这里,TextEditor 不应该担心 SpellChecker 实现。SpellChecker 将被独立实现,并在 TextEditor 实例化时提供给 TextEditor。此整个过程由 Spring 框架控制。
在此,我们从 TextEditor 中删除了全部控制权,并将其保存在其他地方(即 XML 配置文件),并且依赖项(即类 SpellChecker)正在通过 Class Constructor 注入到类 TextEditor 中。因此,依赖注入(DI)已经“反转”了控制流,因为您实际上已经将依赖委托给某个外部系统。
注入依赖关系的第二种方法是通过 TextEditor 类的 Setter Methods ,我们将在其中创建 SpellChecker 实例。此实例将用于调用 setter 方法来初始化 TextEditor 的属性。
因此,DI 以两种主要形式存在,以下两个小章节将用示例介绍它们 −
Sr.No. |
依赖注入类型及说明 |
1 |
Constructor-based dependency injection 基于构造函数的 DI 在容器使用一些参数(每个参数表示对其他类的依赖关系)调用类构造函数时完成。 |
2 |
Setter-based dependency injection 基于 setter 的 DI 由容器在调用无参数构造函数或无参数静态工厂方法来实例化 bean 之后,通过在您的 bean 上调用 setter 方法来完成。 |
您可以混合使用基于构造函数的 DI 和基于 setter 的 DI,但一个好经验法则是对强制依赖关系使用构造函数参数,对可选依赖关系使用 setter。
使用 DI 原则的代码更简洁,当对象获得其依赖项时,解耦将更加有效。对象不会查找其依赖项,并且不知道依赖项的位置或类,而是 Spring 框架负责所有操作。