【问题标题】:Why we say Dependency Injection is a Java Spring framework feature, instead of Java language feature?为什么我们说依赖注入是 Java Spring 框架的特性,而不是 Java 语言特性?
【发布时间】:2017-08-05 13:47:12
【问题描述】:
  1. 我是 Java Spring 框架的新手。在一些文章中,他们说 Spring 框架具有依赖注入。既然 Spring 是基于 Java 的,为什么不说 Java 语言具有依赖注入特性呢?这样的问题让我困惑了一段时间。除了 Java 和 Spring,我对 ASP.NET MVC 和 C# 也有这个问题。

  2. 以下是 Spring 依赖注入代码示例。如果我用Java创建一个小程序,它也可以工作,对吧?

春天:

package com.example.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class DatabaseAccountService implements AccountService {

    private final RiskAssessor riskAssessor;

    @Autowired
    public DatabaseAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
    }

    // ...

}

Java:

public class DatabaseAccountService implements AccountService {

    private final RiskAssessor riskAssessor;

    public DatabaseAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
    }

    // ...

}

更新(这是我困惑的地方):在纯Java中,我认为如果A类依赖于B类。我们创建A类和B类之后,我们只需要去A类,然后做'公共A(B b)'。除此之外,我们还应该做什么?

【问题讨论】:

  • Spring 是一个工具,它允许应用Dependency Injection 模式。与其说 Java 有 DI,不如说 DI 是 OOP 语言的一种模式。你可以在没有工具的情况下练习 DI,称为Pure DI
  • @Steven 是否有任何 OOP 语言不支持 DI 模式?
  • @Steven 在我的第二个问题中,Java 版本的代码也可以,对吧?
  • 我不知道。
  • DI 是关于如何组织代码的全部内容,不需要语言的“支持”,也不需要任何特殊的库。 Spring 所做的只是让 DI 比手动操作更容易。 (它也有自己的一系列问题,这就是为什么有些人选择不使用 Spring 而仍然保留 DI。)

标签: java spring spring-mvc dependency-injection


【解决方案1】:

1) 因为在 Spring automated 依赖注入已经准备好使用特性。在纯 java 中,您必须自己查找或创建依赖项,然后将其注入到依赖项中。

注意词自动。严格来说,是的,依赖注入已经存在于纯 Java 中,
但作者肯定会提到自动的。

2) 你的代码可以工作,但你必须自己找到或创建一个 RiskAssessor 实例,如果你正在创建它(也就是说 Spring 没有为你做),你必须全力以赴它的依赖关系也是如此,然后才构造 DatabaseAccoutService。

如果 DatabaseAccountService 的依赖依赖于它们自己的很多依赖,你会感谢 Spring 为你做的工作。希望:)

---广告您的更新: 是的,差不多就是这样。多亏了这样的构造函数 A(B b) 依赖 b 被注入到类 A 的实例中。只是不要忘记,您将希望在某处以 B 类的实例作为参数实际调用构造函数 A。 这就是您需要有 B 的实例才能将其作为参数传递的地方。你也必须创建它,并用它来创建它需要创建的任何东西。 这就是为什么许多人使用 DI 框架来收集依赖项并注入它们的原因。

【讨论】:

  • "在普通的java中,你必须自己找到或创建你的依赖,然后将它注入到dependee"怎么做?我想我只需要为 RiskAssessor 定义一个新类,然后在我的 DatabaseAccountService 类中,我可以直接使用 public DatabaseAccountService(RiskAssessor riskAssessor),这样可以吗?
  • 您可能已经在很多地方这样做了。像这样:新的 DatabaseAccountService (someRiskAssessorInstance);从您将调用 DAS 构造函数的确切位置无关紧要。依赖项 (someRiskAssessorInstance) 被注入到 DatabaseAccountService 的实例中。
【解决方案2】:
  1. 因为除了 Spring 之外,您还有其他提供依赖注入的框架。 Java 是一种通用语言,许多框架都是为了完成某些“工作”和要求而构建的,以使它们更容易完成。

假设您需要使用钻头在墙上钻孔。您是要在每次需要钻孔时自己制作钻头,还是要重复使用相同的钻头,只需为其提供动力? https://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html

  1. 当您在没有依赖注入的情况下实例化 DataBaseAccountService 时,您的 RiskAssessor 可以是该类的任何实例。但是,当您有 DI 时,基本上框架将确保将正确的(如果没有歧义)实例 bean 分配给该字段。它确保您必须在您的配置类中定义您的 bean,为其赋予某些属性,然后在整个应用程序中使用具有相同属性和功能的相同 bean,而不是在每次需要时都重新实例化它。

【讨论】:

  • 看起来你的答案是我们需要依赖注入的原因,但我的问题不是问我们为什么需要 DI。
  • @QuestionContributor Spring 框架不仅仅是一个 DI 提供者。您使用的任何框架都会提供给您。如果您的问题Why don't we say Java language has Dependency Injection feature since Spring is based on Java? 仍然存在问题,我可以说:Java 语言有能力让您构建自己的 DI,但是为什么当您拥有 Spring(或其他支持 DI 的框架)时。 Spring 基于 Java,就像钻头基于许多组件一样,这些组件将为您提供钻孔的能力。您还想建立自己的钻头吗?也许吧。
  • "Java 语言有能力让您构建自己的 DI" 这就是我感到困惑的地方。为什么你说我们需要建立你自己的 DI?我想如果A类依赖于B类。创建A类和B类后,我们只需要去A类,然后做'public A(B b)'。除此之外,我们还应该做什么?谢谢。
  • 我并不是说你“需要”,只是说你“可以” :D 对于依赖类:只是为了澄清这一点,你也可以通过字段注入,而不仅仅是由构造函数(即使构造函数注入“更聪明”,但现在让我们忽略它)。假设您的 A 类有一个私有字段 B 并且它依赖于它。您不必通过构造函数注入它,您可以简单地说 @Autowired 对私有字段 B dependencyB;并且一旦实例化 A,dependencyB 将自动初始化。使用您自己的实现,您将不得不说 setB(dependB)..
  • 我知道你提到的。但是你能直接回答我的这个问题吗''我认为如果A类依赖于B类。创建A类和B类之后,我们只需要去A类,然后做'public A(B b)'。除此之外,我们还应该做什么?”我想知道我还应该在 Pure Java 中而不是 Spring 中做什么才能让 DI 工作。对不起我的问题,但我想知道。
猜你喜欢
  • 2011-12-31
  • 2010-12-31
  • 2021-02-24
  • 1970-01-01
  • 2016-08-25
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 2014-06-29
相关资源
最近更新 更多