如何在Google Guice中创建实现的实例

时间:2015-07-20 10:58:39

标签: java dependency-injection guice inject

我是Google Guice的新手,需要一些帮助。我创建了一个这样的模块:

public interface Foo {
  Bar doSomething();
}

public class MyFoo implements Foo {
  Bar doSomething() {
    // create an instance of MyBar
  }
}

public interface Bar {
  void run();
}

public interface MyBar implements Bar {
  void run();
}

public class MyModule extends AbstractModule {

  @Override
  protected void configure() {
    bind(Foo.class).to(MyFoo.class);
  }      
}

我的问题是:在课堂上创建MyBar实例的正确方法是什么?#34; MyFoo"?这样做感觉不对:

public class MyFoo implements Foo {
  Bar doSomething() {
    MyBar mybar = new MyBar();
    return mybar;
  }
}

当我需要MyBodule时,是否可以通过MyModule注入新的MyBar实例,或者我是否必须在MyBar的构造函数中注入工厂来创建MyBar实例? 如果我必须使用工厂,我可以控制通过模块生成哪个实现吗?

2 个答案:

答案 0 :(得分:5)

也许您正在寻找提供商?提供者或多或少是工厂,它们是Guice API的一部分,因此您无需实施它们。

public class MyFoo implements Foo {
  @Inject Provider<MyBar> myBarProvider;

  Bar doSomething() {
    return myBarProvider.get(); // returns a new instance of MyBar
  }
}

有关详细信息,请参阅https://github.com/google/guice/wiki/InjectingProviders

答案 1 :(得分:1)

您可以使用Setter或Constructor Injection ,如下所示:

public class MyFoo implements Foo {

    //constructor based injector
    @Inject
    public MyFoo(MyBar myBar){
        this.myBar=myBar;
    }

     //setter method injector
    @Inject
    public void setBar(MyBar myBar){
        this.myBar=myBar;
    }

    Bar doSomething() {
    // create an instance of MyBar
  }
}

MyBar在你的案例which can not be instantiated 中是Interface,你必须提供相同的具体实现,然后在你的Module中绑定并通过Setter或者注入它构造函数注入如上所述。

Setter注射示例:

<强> MyModule.java

import com.google.inject.AbstractModule;

public class MyModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(Foo.class).to(MyFoo.class);
        bind(Bar.class).to(MyBar.class);
    }
}

<强> MyBar.java

public class MyBar implements Bar {

    public void run() {
        System.out.println("Hello Bar");
    }
}

<强> MyFoo.java

import com.google.inject.Inject;

public class MyFoo implements Foo {
    private Bar bar;

    // setter method injector
    @Inject
    public void setBar(Bar myBar) {
        this.bar = myBar;
    }

    public Bar doSomething() {
        return bar;
    }
}