什么是依赖注入?

时间:2012-12-05 11:45:19

标签: java dependency-injection import jar

  

可能重复:
  What is Inversion of Control?

我真的对依赖注入的概念感到困惑。

我对软件领域很陌生,我对以下情况有疑问。假设我的java代码需要一个Json解析器类,所以我在使用Json参数执行java程序时添加classpath jar。我的程序依赖于Json jar,所以这意味着我在这里进行依赖注入

另一个例子是,使用import语句确实解决了用户类依赖于其他类的问题(比如java中的Date)因此所有这些都是依赖注入的概念

我正在制作这个概念。

提前致谢。

5 个答案:

答案 0 :(得分:8)

这与将组件链接在一起的方式有很大关系。例如在上面,我希望你将解析器注入需要它的类中。 e.g。

而不是:

public class MyParserUsingClass {
   ...
   public MyParserUsingClass() {
      this.parser = new Parser();
   }
}

你会这样做:

public class MyParserUsingClass {
   ...
   public MyParserUsingClass(Parser injectedParser) {
      this.parser = injectedParser;
   }
}

为什么这样?使用解析器的类并不真正关心解析器的来源,应该使用接口而不是具体的实例。通过注入解析器,您可以根据具体情况提供不同的实例,将其模拟出来进行测试等。否则,类只会在内部创建它而您无法控制它。这对于可配置组件,通过网络进行通信的组件,重量级组件等尤其重要。

答案 1 :(得分:1)

在您的具体示例中,依赖注入将如下所示:

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提供该接口的任何实现,这不依赖于您选择使用的具体实现。

答案 2 :(得分:1)

假设您有一个名为MyCustomParser的工作的类。 现在你想允许在该类中注入解析器以获得与你将注入的解析器类型不同的行为(json可以改变,你想用另一种方式来解析等)。 因此,您应该使用名为(按实例)Interface的方法创建IParser - ParseIt 现在,根据您希望如何进行解析,您可以使用此方法的不同实现。 您需要做的就是将此接口传递给将使用它的类MyCustomParser(您可以将其作为构造函数中的参数传递)。 在这种情况下,您将在MyCustomParser

中注入Parser

答案 3 :(得分:1)

严格意义上的依赖注入与导入类或将jar文件添加到类路径无关。它旨在支持编程到接口原理,它是一种控制反转的形式。

它带来的主要好处是您的代码不依赖于显式依赖项实现,而是使用抽象代替。您依赖于一个接口,该接口的实现类的某个实例将在运行时在您的类中“注入”(作为构造函数参数,某些setter,或者 - 在我看来 - 糟糕的选择 - 实例字段)。

因此,您可以更改持久层,而无需触及服务组件中的代码,因为您的服务类只关心某些DAO / Repository接口,并且您将为它们提供不同的实现。< / p>

答案 4 :(得分:0)

依赖注入更多的是减少一个类必须创建它依赖的事物实例的实例。

依赖注入的目的是通过一些外部机制将这些依赖关系“赋予”消费类。常用方法包括通过构造函数传递依赖项,或将它们设置为类的公共“可设置”属性。

例如,通过构造函数的依赖注入看起来像这样:

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接口,将其留给一些更高的控制代码,以确定最适合做这项工作的适当的具体类型。