玩具示例:

public class MyModule extends AbstractModule {
  private static final Foo foo;

  public MyModule(Foo foo) {
    this.foo = foo;
  }

  @Override
  public void configure() {
    bind(Bar.class).toProvider(new Provider<Bar>() {
      @Override public Bar get() {
        return foo.getBar();
      }
    });
  }
}

这让我可以懒惰地调用存储在 .getBar() 字段中的用户提供的 Foo 实例的 MyModule 方法。但是现在 provider has its own dependencies - 因此我需要定义一个非匿名类,我指定了一个 @Inject 构造函数。就像是:
public class MyModule extends AbstractModule {
  private static final Foo foo;

  public MyModule(Foo foo) {
    this.foo = foo;
  }

  @Override
  public void configure() {
    bind(Bar.class).toProvider(BarProvider.class);
  }

  BarProvider implements Provider<Bar> {
    private Baz baz;

    @Inject BarProvider(Baz baz) {
      this.baz = baz;
    }

    @Override public Bar get() {
      return foo.getBar(baz);
    }
  }
}

完美的!除了 Guice doesn't like this ...



所以,我陷入了困境。我需要同时访问模块上的字段和来自 Provider 类的注入(inject)类型。有没有办法做到这一点?

注意: 这个玩具示例排除了一些实际的复杂性——特别是 bind() 语句更复杂,这就是为什么我不能简单地定义一个 @Provides 方法。

最佳答案

在某种程度上,注入(inject)内部类是不可能的,因为 Guice 无法反射性地创建没有外部父实例的内部实例(相当于神秘的 outerInstance.new InnerInstance() 语法)。

一些选项:

  • 使 Foo 可通过您的图表注入(inject),可能隐藏在 PrivateModule 中,因此它不会暴露在您的整个图表中(如果这对您很重要)。
  • 使用匿名内部提供程序(或提取的等效项),并从 AbstractModule 的 Provider<Baz> 方法获取 getProvider(Class<T>)。如果您尝试在创建 Injector 之前调用它,您会得到一个异常,但是对于按照您的方式创建 Provider 来说,这可能不是问题。
  • 将您的 bind 发布到玩具问题之外,看看是否可以巧妙地使用 @Provides

  • 相关:Accessing Guice injector in its Module?

    关于java - 如何将引用模块中字段的匿名提供者移动到单独的类中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42015063/

    10-16 08:37