我正在扩展Guice的AbstractModule
并且在扩展类中我需要访问Guice的注入器。这可能,如果是的话,怎么样?
答案 0 :(得分:50)
这是一个不寻常的请求。模块更像是配置文件而不是逻辑文件:读取模块以创建注入器,然后一旦创建注入器,模块就完成了它的工作。对于一个简单的模块,在模块准备好被丢弃之前,注入器实际上不存在。
在任何情况下,您应该通常请求Provider<X>
,而不是请求Injector获取X类。 Guice将inject an X
or Provider<X>
for any binding of X
, Provider<X>
, or @Provides X
,所以你几乎总能做到这一点。也就是说,注入Injector将允许您反射性地获取实例,或者检查Injector的绑定(等)。
以下是一些需要从模块中访问Injector的有效原因/设计:
@Provides
方法中:模块可以在methods annotated with @Provides
中包含迷你提供程序。请记住Injector
is injectable:如果您需要其中一种方法中的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
}
}
AbstractModules正是因为这个原因而公开getProvider()
,但如果在注入器准备好提供它之前在该Provider上调用get()
(例如在配置时),则会出现错误:< / p>
public class TwoModule extends AbstractModule {
@Override public void configure() {
bind(Thingy.class).toInstance(
new MyThingy(8675309, getProvider(Another.class)));
}
}
你可以打电话给getProvider(Injector.class)
,但我不知道这是否有效,我不知道你为什么要这样做。
这是一个坏主意;在运行所有配置方法之前,Guice尚未准备好提供实例。你可以得到的最接近的是create a child 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);
}
}
答案 1 :(得分:0)
您可以将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) { ... }
}