Java 什么是依赖注入?
可能重复:Java 什么是依赖注入?,java,dependency-injection,import,jar,Java,Dependency Injection,Import,Jar,可能重复: 我真的对依赖注入的概念感到困惑 我对软件领域非常陌生,我对下面的场景有怀疑。假设我的java代码需要一个Json解析器类,所以我在使用classpath参数执行java程序时添加了Jsonjar。我的程序依赖于Jsonjar,所以这意味着我在这里进行依赖注入 另一个例子是,使用import语句确实解决了用户类依赖于其他类(如java中的Date)的问题,所以所有这些都是依赖注入的概念 我在这里提出这个概念 提前感谢。依赖注入更多的是减少实例,在这些实例中,类必须创建自己依赖的事物的
我真的对依赖注入的概念感到困惑 我对软件领域非常陌生,我对下面的场景有怀疑。假设我的java代码需要一个
Json
解析器类,所以我在使用classpath
参数执行java程序时添加了Json
jar。我的程序依赖于Json
jar,所以这意味着我在这里进行依赖注入
另一个例子是,使用import
语句确实解决了用户类依赖于其他类(如java中的Date
)的问题,所以所有这些都是依赖注入的概念
我在这里提出这个概念
提前感谢。依赖注入更多的是减少实例,在这些实例中,类必须创建自己依赖的事物的实例 依赖项注入的目的是通过某种外部机制将这些依赖项“给予”消费类。常用方法包括通过构造函数传入依赖项,或将它们设置为类的公共“可设置”属性 例如,通过构造函数的依赖项注入可以如下所示:
public class Parser
{
private IJsonParser parser;
public Parser(IJsonParser parser) {
this.parser = parser;
}
}
public class Parser
{
private IJsonParser parser;
public Parser() {
this.parser = new JsonParser();
}
}
这样就不需要解析器类执行以下操作:
public class Parser
{
private IJsonParser parser;
public Parser(IJsonParser parser) {
this.parser = parser;
}
}
public class Parser
{
private IJsonParser parser;
public Parser() {
this.parser = new JsonParser();
}
}
这遵循了单一责任的原则-Parser类不需要负责创建JsonParser,也不应该关心它使用什么特定的JsonParser-它关心的只是它需要一些完成IJsonParser接口指定工作的东西,然后让更高级别的控制代码来决定最适合做这项工作的具体类型。更重要的是如何将组件链接在一起。e、 在上面,我希望您将解析器注入到需要它的类中。e、 g 而不是:
public class MyParserUsingClass {
...
public MyParserUsingClass() {
this.parser = new Parser();
}
}
你会做:
public class MyParserUsingClass {
...
public MyParserUsingClass(Parser injectedParser) {
this.parser = injectedParser;
}
}
为什么要这样做?使用解析器的类并不真正关心解析器来自何处,应该真正使用接口而不是具体实例。通过注入解析器,您可以根据具体情况提供不同的实例,模拟它进行测试等。否则类将只是在内部创建它,您将无法控制它。这对于可配置组件、跨网络通信的组件、重量级组件等尤其重要。在您的特定示例中,依赖项注入看起来像:
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
,这不取决于您选择使用哪个具体实现。假设您有一个类,该类的DAE作业名为MyCustomParser
。
现在,您希望允许在该类中注入解析器,以获得与要注入的解析器类型不同的行为(json可能会改变,您希望使用另一种方式来解析等等)。
因此,您应该使用名为(按实例)ParseIt
现在,根据您希望如何进行解析,您可以使用此方法的不同实现。
您只需将此接口传递给将使用它的类MyCustomParser
(您可以将其作为构造函数中的参数传递)。
在本例中,您正在
MyCustomParser
类中注入解析器,严格意义上讲,依赖注入与导入类或向类路径添加jar文件无关。这是为了支持编程到接口的原则,这是一种控制反转的形式
它带来的主要好处是代码不依赖于显式依赖实现,而是使用抽象。您依赖于一个接口,并且该接口的某个实现类实例将在运行时“注入”到您的类中(作为构造函数参数、某个setter,或者——我认为这是一个错误的选择——实例字段)
因此,例如,您可以在不涉及服务组件中的代码的情况下更改持久性层,因为您的服务类只关心一些DAO/存储库接口,您将为它们提供不同的实现。这根本不是依赖注入。谷歌IoC(控制反转)来获得更好的感觉。不,这两个都不是依赖注入;这些只是依赖关系。查阅“控制反转”来阅读这个主题。@assylias:我不这么认为。我把DI概念和其他概念混淆了。我没有问它到底是什么。
为什么这样做?
解释+1。谢谢