Guice:注入一个用于实现抽象方法的参数

时间:2013-10-01 03:34:11

标签: java dependency-injection abstract-class guice

以下是我遇到的问题的一个示例:

public interface IFoo { ... }

public abstract class Helper implements IFoo {
  public Helper() { ... }

  protected abstract X helperMethod();
}    

public class Foo extends Helper {
  private final String aaa;

  @Inject
  public Foo(String aaa) { this.aaa = aaa; }

  @Override
  X helperMethod() { doSomethingUsingWhatsInjected(aaa); }
}

问题在于,当我将IFoo绑定到Foo时:

bind(IFoo.class).to(Foo.class).in(Singleton.class);

似乎helperMethod()aaa被注入之前被调用,因为我看到aaanull。但是,如果我不使用类Helper并直接在Foo内嵌其所有代码,guice就不会挣扎。

这两种方法有什么区别?在我们知道helperMethod()的实施位置之前,为什么要调用IFoo?我们可以使用Helper和注射吗?

1 个答案:

答案 0 :(得分:2)

您确定没有从helperMethod的构造函数中调用Helper吗?您从发布的代码中省略了该部分,但它会与您看到的行为相匹配。

public class Test {
  interface IFoo { }

  static abstract class Helper implements IFoo {
    Helper() { helperMethod(); }
    abstract void helperMethod();
  }

  static class Foo extends Helper {
    private final String aaa;

    Foo(String aaa) { this.aaa = aaa; }

    @Override
    void helperMethod() { System.out.println(String.valueOf(aaa)); }
  }

  public static void main(String[] args) {
    // Call helperMethod twice:
    // once in the Helper.Helper(), once right here.
    new Foo("expected").helperMethod();
    // output:
    //   null
    //   expected
  }
}

Foo做的第一件事就是隐式调用它的超类构造函数,就好像你键入了super();这必然发生在子类构造函数中的第一个语句。因此,即使在设置aaa之类的最终变量之前也会发生这种情况,因此Foo中的重写方法将aaa视为null。在我的示例中,这不是Guice特有的,但Guice注入可以像其他任何东西一样触发构造函数。

This StackOverflow answer提供了有关此问题的更全面的讨论。