38

我正在扩展 Guice AbstractModule,在扩展类中我需要访问 Guice 的注入器。这可能,如果是,如何?

4

2 回答 2

60

这是一个不寻常的要求。模块更像是配置文件而不是逻辑文件:模块被读取以创建注入器,然后一旦注入器被创建,模块就完成了它的工作。对于一个简单的模块,在模块准备好被丢弃之前,注入器实际上并不存在。

在任何情况下,您通常都应该请求一个Provider<X>. Guice 将为,的任何绑定注入or ,XProvider<X>XProvider<X>@Provides X因此您几乎总是可以这样做。也就是说,注入 Injector 将允许您以反射方式获取实例,或检查 Injector 的绑定(等)。

以下是一些需要从模块内访问喷油器的正当理由/设计:

在一个@Provides方法中:

模块可以在带有注释@Provides的方法中包含微型提供程序。请记住,它Injector是可注入的:如果您需要在其中一种方法中使用 Injector,则可以将其作为参数接受:

public class OneModule extends AbstractModule {
  @Override public void configure() { /* ... */ }

  @Provides YourDependency getYourDependency(Injector injector) {
    return injector.getInstance(Class.forName(yourDependencyName));
  }

  @Provides Something getSomething(SomethingImpl something) {
    return initialize(something); // preferred: only ask for what you need
  }

  @Provides SomethingElse getSomethingElse(Provider<Thing> thingProvider) {
    return new SomethingElse(thingProvider); // asking for a provider works too
  }
}

要在您的 configure() 中获取提供程序:

AbstractModules 正是出于这个原因而暴露的,尽管如果在注入器准备好提供它之前调用该 Provider(例如在配置时)getProvider(),您会收到一个错误:get()

public class TwoModule extends AbstractModule {
  @Override public void configure() {
    bind(Thingy.class).toInstance(
        new MyThingy(8675309, getProvider(Another.class)));
  }
}

您可能可以打电话getProvider(Injector.class),但我不知道这是否有效,我不知道您为什么要这样做。

要在您的 configure() 中获取实例:

这是一个坏主意; 在所有配置方法运行之后,Guice 才准备好提供实例。最接近的方法是使用其他模块创建一个子 Injector并将其传递给该模块,但即使这样也很少需要。

public class MainClass {
  public static void main(String[] args) {
    Injector firstStage =
        Guice.createInjector(new OtherModule1(), new OtherModule2());
    // An alternative design would @Inject-annotate fields in ThreeModule
    // and get it from firstStage, but that's nonstandard and may be confusing.
    Injector secondStage =
        firstStage.createChildInjector(new ThreeModule(firstStage));
  }
}

public class ThreeModule extends AbstractModule {
  private final Injector otherInjector;

  public ThreeModule(Injector otherInjector) { 
    this.otherInjector = otherInjector;
  }

  @Override public void configure() {
    bindStuffBasedOn(otherInjector);
  }
}
于 2013-04-13T18:49:18.837 回答
1

Injector您可以在您的课程或提供者中注入,但应该稀疏地使用它

我在这里找到它:https ://groups.google.com/d/msg/google-guice/EiMDuDGei1Q/glxFhHKHHjsJ

另见:https ://github.com/google/guice/wiki/InjectingTheInjector

public class MyClass
{
    @Inject
    public MyClass(Injector injector) { ... }
}

public class MyModule extends AbstractModule {
    ...

    @Provides
    public Something provideSomething(Injector injector) { ... }

}
于 2020-07-09T10:04:34.953 回答