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