Java 在其模块中访问Guice喷油器?

Java 在其模块中访问Guice喷油器?,java,dependency-injection,guice,Java,Dependency Injection,Guice,我正在扩展Guice的抽象模块,在扩展类中,我需要访问Guice的注入器。有可能吗?如果有,怎么可能 这是一个不寻常的请求。模块更像配置文件而不是逻辑文件:读取模块以创建喷油器,然后在创建喷油器后,模块完成其工作。对于一个简单的模块,喷油器实际上不存在,直到模块准备丢弃 在任何情况下,通常都应该请求提供程序,而不是请求喷油器获取X类。Guice会的,所以你几乎总是可以这样做。也就是说,注入注入器将允许您以反射方式获取实例,或者检查注入器的绑定(等等) 以下是需要从模块内访问喷油器的几个有效原因/

我正在扩展Guice的
抽象模块
,在扩展类中,我需要访问Guice的注入器。有可能吗?如果有,怎么可能

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

在任何情况下,通常都应该请求
提供程序
,而不是请求喷油器获取X类。Guice会的,所以你几乎总是可以这样做。也就是说,注入注入器将允许您以反射方式获取实例,或者检查注入器的绑定(等等)

以下是需要从模块内访问喷油器的几个有效原因/设计:

@提供的
方法中:
模块中可以包含微型提供程序。请记住:如果您在这些方法中需要一个喷油器,您可以将其作为一个参数接受:

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
  }
}
您可能可以调用
getProvider(Injector.class)
,但我不知道这是否有效,也不知道您为什么要这样做

要在configure()中获取实例,请执行以下操作: 这是个坏主意;在所有configure方法都运行之后,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);
  }
}

您可以在类或提供程序中注入
注入器
,但应该少用

我在这里找到的:

另见:


我同意,这是一个不寻常的请求,可能暗示了设计的味道go@ilikeorangutans喜欢这样的评论;他们总是让我觉得我的设计有味道,但不知道如何改进:虽然不寻常,但我不认为它总是一个糟糕的设计,哈哈。我们有一个场景,我们希望从它的类中动态地获取一个实例。当您接近动态场景(反射等)时,您开始需要高级的“元”功能。@FerranMaylink我自己说:我的反对与动态访问或使用注入器无关。当然,在可能的情况下明确您的依赖关系是有意义的,并且尽可能减少对Guice特定组件的使用,但是通过Injector进行反射访问是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);
  }
}
public class MyClass
{
    @Inject
    public MyClass(Injector injector) { ... }
}

public class MyModule extends AbstractModule {
    ...

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

}