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

2023-12-23

我正在扩展吉斯的AbstractModule在扩展类内部,我需要访问 Guice 的注入器。有可能吗,如果有的话,怎么可能?


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

在任何情况下,您通常应该请求一个,而不是请求一个 Injector 来获取 X 类Provider<X>。吉斯将注入一个X or Provider<X>对于任何绑定X, Provider<X>, or @Provides X https://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/Injector.html,所以你几乎总是可以这样做。也就是说,注入注入器将允许您反射性地获取实例,或者检查注入器的绑定(等等)。

以下是需要从模块内访问注入器的一些有效原因/设计:

In a @Provides method:

模块可以包含微型提供者注释为的方法@Provides https://github.com/google/guice/wiki/ProvidesMethods。请记住Injector可注射 https://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/Injector.html:如果您在这些方法之一中需要注入器,您可以接受它作为参数:

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()中获取提供者:

AbstractModule暴露getProvider() https://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/AbstractModule.html#getProvider-java.lang.Class-正是出于这个原因,尽管如果您调用,您会收到错误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 才准备好提供实例。你能得到的最接近的是创建一个子注入器 https://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/Injector.html#createChildInjector(com.google.inject.Module...)使用其他模块并将其传递到此模块中,但即使如此也很少需要。

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);
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

访问其模块中的 Guice 注入器? 的相关文章

随机推荐