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 Framework控制。
在这里,我们已经从TextEditor中删除了总控制并将其保存在其他地方(即XML配置文件),并且通过Class Constructor将依赖项(即类SpellChecker)注入到TextEditor Class Constructor 。 因此,控制流已经被依赖注入(DI)“反转”,因为您已经有效地将依赖性委托给某些外部系统。
注入依赖的第二种方法是通过TextEditor类的Setter Methods ,我们将在其中创建一个SpellChecker实例。 此实例将用于调用setter方法以初始化TextEditor的属性。
因此,DI存在两个主要变体,以下两个子章节将通过示例涵盖它们 -
Sr.No. | 依赖注入类型和描述 |
---|---|
1 | 基于构造函数的依赖注入 当容器调用具有许多参数的类构造函数时,完成基于构造函数的DI,每个参数表示对另一个类的依赖。 |
2 | 基于Setter的依赖注入 基于setter的DI是在调用无参数构造函数或无参数静态工厂方法来实例化bean之后,通过容器调用bean上的setter方法来完成的。 |
您可以混合使用基于构造函数和基于Setter的DI,但使用构造函数参数作为必需依赖项和使用可选依赖项的setter是一个很好的经验法则。
使用DI原理的代码更清晰,当对象提供其依赖项时,解耦更有效。 该对象不查找其依赖项,也不知道依赖项的位置或类,而是Spring框架对所有内容都进行了处理。