在其模块中访问 Guice 注入器? [英] Accessing Guice injector in its Module?

查看:20
本文介绍了在其模块中访问 Guice 注入器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在扩展 Guice 的 AbstractModule 并且在扩展类中我需要访问 Guice 的注入器.如果是的话,那可能吗?

I am extending Guice's AbstractModule and inside of the extending class I need access to Guice's injector. It that possible, if yes, how?

推荐答案

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

This is an unusual request. Modules are more like config files than logic files: The Module is read to create the Injector, and then as soon as the Injector is created the module has done its job. For a simple Module, the Injector literally doesn't exist until the Module is ready to be discarded.

在任何情况下,您通常应该请求一个 Provider,而不是请求注入器来获取类 X.Guice 将 XProviderProvider 的任何绑定注入 XProvider,或@Provides X,所以你几乎总是可以这样做.也就是说,注入 Injector 将允许您反射性地获取实例,或检查 Injector 的绑定(等).

In any case, rather than requesting an Injector to get class X, you should typically request a Provider<X>. Guice will inject an X or Provider<X> for any binding of X, Provider<X>, or @Provides X, so you can almost always do this instead. That said, injecting the Injector will allow you to get an instance reflectively, or to inspect the Injector's bindings (etc).

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

Here are a few valid reasons/designs that would require accessing an Injector from within a Module:

模块可以在@Provides注释的方法中包含迷你提供者.请记住 Injector 是可注入的:如果您需要在其中一种方法中使用 Injector,您可以将其作为参数接受:

Modules can contain mini-providers in methods annotated with @Provides. Remember that Injector is injectable: If you need an Injector in one of those methods, you can just accept it as a parameter:

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 公开 getProvider() 正是出于这个原因,但如果您在注入器之前对该 Provider 调用 get() ,则会出现错误准备提供它(例如在配置时):

To get a Provider in your configure():

AbstractModules expose getProvider() for exactly this reason, though you'll get an error if you call get() on that Provider before the injector is ready to provide it (such as at configuration time):

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

您可能可以调用 getProvider(Injector.class),但我不知道这是否有效,也不知道您为什么要这样做.

You can probably call getProvider(Injector.class) but I don't know whether that works and I don't know why you'd want to.

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

This is a bad idea; Guice is not ready to provide instances until after all of the configure methods run. The closest you can get is to create a child Injector using the other modules and pass it into this module, but even that is rarely needed.

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);
  }
}

这篇关于在其模块中访问 Guice 注入器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆