依赖注入java

时间:2016-01-19 21:28:27

标签: java dependency-injection

以下是依赖注入的有效示例。

public class Employee {
    private String name;
    private String company;

    public Employee(String name, String company){
        this.name = name;
        this.company = company;
    }

    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
    public String getCompany(){
        return company;
    }
    public void setCompany(String company){
        this.company = company;
    }
}

Application类依赖于Employee

public class Application {

    private static Employee emp;
    private static String name;
    private static String company;

    public Application(Employee emp){
        this.emp = emp;
    }

    public static String getApplication(){
        name = emp.getName();
        company = emp.getCompany();
        return "Name: " + name + "\nCompany: " + company;
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Employee emp1 = new Employee("John", "ABC");
        Application app1 = new Application(emp1);
        System.out.println(app1.getApplication());
    }

}

3 个答案:

答案 0 :(得分:3)

您在此处成功注入了依赖项:

Employee emp1 = new Employee("John", "ABC");
Application app1 = new Application(emp1);

因为Application的实例需要Employee的实例,因此在其构造函数上通告必须提供一个实例。这是反转该依赖性的教科书示例。 (或者,简化,"要求,不要实例化。")

但是,存储这种依赖关系的方式有点可疑:

private static Employee emp;

在提供的示例中,这可能不会导致任何问题。但是当你需要创建另一个需要Application的依赖实例的Employee实例时会发生什么?第二个例子将覆盖第一个并破坏其依赖性。

如果实例需要依赖项,那么实例应该存储依赖项:

private Employee emp;

(甚至可以使它final,除非你有理由在实例的生命期间改变它。)

当然,名称Application 的语义暗示只有一个实例。但在这种情况下,单例实例可能比static成员更好。作为面向对象编程的一般经验法则,请谨慎使用static成员。他们有自己的用途,但他们很容易也有误用。

答案 1 :(得分:1)

这是DI的一个例子。你这样做:

Employee emp1 = new Employee("John", "ABC");
Application app1 = new Application(emp1);

您可以在此处实施:

 public Application(Employee emp){
    this.emp = emp;
}

这种DI被称为构造函数注入。

如果您的应用程序类中有一名员工,并且让您使用该setter设置员工,那么它将被称为 setter injection

答案 2 :(得分:0)

首先,您可能想了解何时使用依赖注入。 注入一个没有功能的简单类的实例对我来说毫无意义。

您通常使用一个具有行为的类的接口,它不仅仅是数据的包装器。删除静态并可能添加一个final,并在您的注入中发送该接口的实现实例。

像这样:

public class TextEditor {
   /*Interface SpellChecker**/
   private final SpellChecker spellChecker;
   private String text; 

   /**An implementation for the SpellChecker is provided*/
   public TextEditor(final SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public Boolean spellCheck(){
      return this.spellChecker.isSpellingCorrectForText(this.text);
   }
}

正如您在上面的示例中所看到的,拼写检查责任被委托给在构造函数中注入的外部依赖项。 TextEditor不需要知道如何拼写检查,他只是用方法调用接口。

为什么我们这样做?尊重SOLID(SRP):https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)

更多信息: https://softwareengineering.stackexchange.com/questions/135971/when-is-it-not-appropriate-to-use-the-dependency-injection-pattern http://www.tutorialspoint.com/spring/spring_dependency_injection.htm