在其模块中访问Guice注入器?

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

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

在任何情况下,您应该通常请求Provider ,而不是请求Injector获取类X. Guice将为XProvider@Provides X任何绑定注入XProvider ,因此您几乎总能执行此操作。 也就是说,注入Injector将允许您reflection性地获取实例,或者检查Injector的绑定(等)。

以下是一些需要从模块中访问Injector的有效原因/设计:

@Provides方法中:

模块可以包含使用@Provides注释的方法中的迷你提供程序。 请记住, Injector是可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 thingProvider) { return new SomethingElse(thingProvider); // asking for a provider works too } } 

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

AbstractModules正是出于这个原因公开了getProvider() ,但是如果在注入器准备好提供它之前调用该Provider上的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); } }