1

我刚开始使用 Guice,所以我的理解可能完全错误。

我有一个接口Foo和一个实现FooImp

我在我的模块中使用了以下代码来注入它:

bind(Foo.class).annotatedWith("Foo").toInstance(foo);  // foo is an instance of FooImp

然后我猜现在在我的代码中Foo,名称注释为“Foo”的实例将被替换为foo

@Named("Foo")
Foo fooInst;   // fooInst will be foo at runtime?

如果我是对的,我该如何实现:

public Foo doSomething() {  // for some reason there must be no arguments
    @Named("Foo")
    Foo fooInst;   // injecting here seems not allowed...?
    fooInst.do();
}
4

3 回答 3

4

您的假设并不完全正确:Guice 用于依赖注入,这意味着您可以将一些接口/类注入到另一个类的构造函数中。

假设您有一个接口Foo和它的实现FooImpl。然后你还有一个类Bar,它依赖于Foo.

public class Bar {

    private Foo foo;

    @Inject
    public Bar(@Named("foo") Foo foo) {
        this.foo = foo;
    }

    //some other methods
}

在您的 Guice 模块中,您必须编写

bind(Foo.class).annotatedWith(Names.named("Foo")).toInstance(foo);
//let's say this is part of the module MyModule extends AbstractModule

一旦你设置了这个,你就可以使用 Guice 的Injector-class 创建一个 main-method 来创建一个对象。像这样:

Injector injector = Guice.createInjector(new MyModule());
Bar bar = injector.getInstance(Bar.class);
//do something with bar

希望这对您有所帮助。如果您有更多问题,请随时问我!

提示:查看Guice的网站,观看那里的视频并仔细阅读 wiki。Guice 是一个非常棒的工具,但是在使用它之前你需要做一些研究。祝你好运!


另外:在我看来 using@Named是一种糟糕的代码风格。您可以更好地定义自己的注释。例如:

@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface FooAnnotation {
}

然后在类中替换@Named("foo")为并在您的模块中替换为。@FooAnnotationBarNames.named("Foo")FooAnnotation.class

于 2013-07-30T19:07:15.540 回答
1

不幸的是,您不能在局部变量上放置注释。这个限制来自 Java 而不是 Guice。根据这个答案,希望我们在未来的 Java 版本中获得这个功能。

但请注意,即使这可行,也不是一个好习惯。依赖注入的思想是从类外部改变依赖的能力。局部变量不适合这种情况,因为它不能从类外部更改。

于 2013-07-30T18:54:48.790 回答
0

其他答案是正确的-您只能注入构造函数或字段。将实例保留为字段是标准做法,这也允许您交换自己的实现以进行测试。

如果您需要在每次调用方法时生成一个新实例,您可以使用Provider. 对于 (or ) 的任何给定绑定Foo@Baz Foo( Provider<Foo>or @Baz Provider<Foo>) 会自动绑定,无需任何额外代码。

public class Bar {
  private Provider<Foo> fooProvider;

  @Inject
  public Bar(@Named("foo") Provider<Foo> fooProvider) {
    this.fooProvider = fooProvider;
  }

  public doSomething() {
    Foo foo = fooProvider.get();
  }
}

当然,如果您使用bind(...).toInstance(...).

于 2013-07-30T22:38:23.673 回答