什么是依赖注入? [复制]
Posted
技术标签:
【中文标题】什么是依赖注入? [复制]【英文标题】:What is meant to be a dependency injection? [duplicate] 【发布时间】:2012-11-23 05:43:28 【问题描述】:可能重复:What is Inversion of Control?
我真的对依赖注入的概念感到困惑。
我是软件领域的新手,我对以下情况有疑问。假设我的 java 代码需要一个 Json
解析器类,所以我在使用 classpath
参数执行 java 程序时添加了 Json
jar。我的程序依赖于Json
jar,所以这意味着我在这里进行依赖注入?
另一个例子是,使用import
语句确实解决了用户类依赖于其他类的问题(如java中的Date
)所以所有这些都是依赖注入的概念 ?
我在哪里提出这个概念。
提前致谢。
【问题讨论】:
这根本不是依赖注入。 Google IoC(控制反转)以获得更好的感觉。 不,这些都不是依赖注入;这些只是依赖关系。查找“控制反转”以了解该主题。 @assylias:我不这么认为。我将 DI 概念与其他概念混淆了。我并没有问它实际上是什么。 【参考方案1】:依赖注入更多是为了减少一个类必须创建它自己依赖的事物的实例的实例。
依赖注入旨在通过一些外部机制将这些依赖“给予”给消费类。常用方法包括通过构造函数传入依赖项,或将它们设置为类的公开“可设置”属性。
例如,通过构造函数进行的依赖注入可能如下所示:
public class Parser
private IJsonParser parser;
public Parser(IJsonParser parser)
this.parser = parser;
这消除了 Parser 类执行以下操作的需要:
public class Parser
private IJsonParser parser;
public Parser()
this.parser = new JsonParser();
这遵循单一职责的原则 - Parser 类不需要负责创建 JsonParser,也不应该关心它使用什么特定的 JsonParser - 它的关注点只是它需要完成指定工作的东西通过 IJsonParser 接口,并将其留给一些更高的控制代码来确定最适合执行该工作的适当具体类型。
【讨论】:
【参考方案2】:更多的是与如何将组件链接在一起。例如在上面,我希望您将解析器注入需要它的类中。例如
代替:
public class MyParserUsingClass
...
public MyParserUsingClass()
this.parser = new Parser();
你会这样做:
public class MyParserUsingClass
...
public MyParserUsingClass(Parser injectedParser)
this.parser = injectedParser;
为什么要这样做?您使用解析器的类并不真正关心解析器的来源,并且应该真正使用接口而不是具体实例。通过注入解析器,您可以根据情况提供不同的实例,将其模拟出来进行测试等。否则该类只会在内部创建它,而您将无法控制它。这对于可配置组件、跨网络通信的组件、重量级组件等尤其重要。
【讨论】:
+1 表示Why do this?
解释。谢谢!【参考方案3】:
在您的具体示例中,依赖注入如下所示:
public class MyParser
private final JsonParser parser;
public MyParser(JsonParser parser)
this.parser = parser;
public Result parse(JsonInput input)
Result = parser.parse(input);
假设JsonParser
是一个接口,您现在可以向MyParser
提供该接口的任何实现,这与您选择使用的具体实现无关。
【讨论】:
【参考方案4】:假设您有一个名为 MyCustomParser
的工作类。
现在您希望允许在该类中注入解析器以获得针对您将注入的解析器类型的不同行为(json 可能会更改,您想使用另一种解析方式等)。
所以你应该创建一个Interface
- IParser
使用一个名为(通过实例)ParseIt
的方法
现在,您可以根据要进行解析的方式对此方法进行不同的实现。
您需要做的就是将此接口传递给将使用它的类MyCustomParser
(您可以在构造函数中将其作为参数传递)。
在这种情况下,您将在 MyCustomParser
类中注入解析器
【讨论】:
【参考方案5】:从严格意义上说,依赖注入与导入类或将 jar 文件添加到类路径无关。它旨在支持对接口的编程原理,它是一种控制反转的形式。
它带来的主要好处是你的代码不依赖于显式的依赖实现,而是使用抽象。您依赖于一个接口,并且该接口的实现类的某个实例将在运行时“注入”到您的类中(作为构造函数参数、某个 setter 或 - 在我看来是错误的选择 - 实例字段)。
因此,您可以在不触及服务组件中的代码的情况下更改持久层,因为您的服务类只关心一些 DAO/Repository 接口,您将为它们提供不同的底层实现。
【讨论】:
以上是关于什么是依赖注入? [复制]的主要内容,如果未能解决你的问题,请参考以下文章