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

2022-09-01 04:28:42

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


答案 1

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

无论如何,您通常应该请求一个 .Guice 将为 X、Provider<X> 或 @Provides X 的任何绑定注入 X 或 Provider<X>,因此您几乎总是可以执行此操作。也就是说,注入注入器将允许您以反射方式获取实例,或检查注入器的绑定(等)。Provider<X>

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

在方法中:@Provides

模块可以在使用@Provides注释的方法中包含微型提供程序。请记住,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正是出于这个原因公开getProvider(),尽管如果你在注入器准备好提供它之前(例如在配置时)调用该提供程序,你会得到一个错误:get()

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

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

要获取配置()中的实例:

这是一个坏主意;在所有配置方法运行之前,Guice 尚未准备好提供实例。您可以获得的最接近方法是使用其他模块创建一个子注入器并将其传递到此模块中,但即使这样也很少需要。

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

答案 2

您可以在类或提供程序中注入 ,但应稀疏地使用它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) { ... }

}

推荐