注入一个 TypeListener
Inject a TypeListener
我有这种情况,我想注入一个 TypeListener
与依赖关系,但它永远不会工作,因为 TypeListener
用于实际执行注入。
我怎样才能完成这件事?有 guicey 方式吗?
备注:
- 我正在使用 Guice 4.0
MyManager
将在Guice::createInjector
之后使用。
MyManager::registerType
和 MyManager::use
都在 Guice::createInjector
returns 之前独占调用。
MyDependency
的存在表明 MyManager
不能用 new
实例化。 Guice::createInjector
回来后我也会用
我创建了以下 SSCCE 来展示我的问题:
import com.google.inject.*;
import com.google.inject.matcher.*;
import com.google.inject.spi.*;
public class MyClass {
public static void main(String[] args) {
Guice.createInjector(new MyModule());
}
static class MyModule extends AbstractModule {
@Override protected void configure() {
TypeListener listener = new MyTypeListener();
requestInjection(listener);
bindListener(Matchers.any(), listener);
}
}
static class MyTypeListener implements TypeListener {
@Inject MyManager manager;
@Override public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
Class<?> rawType = type.getRawType();
manager.registerType(rawType);
encounter.register(new InjectionListener<I>() {
@Override public void afterInjection(I injectee) {
manager.use(rawType, injectee);
}
});
}
}
@Singleton static class MyManager {
@Inject MyManager(MyDependency dependency) { }
void registerType(Class<?> type) { }
void use(Class<?> type, Object injectee) { }
}
static class MyDependency { }
}
我认为至少在某些时候(在测试或代码分析中)类型侦听器与他们正在侦听的类型没有内聚性,因此没有理由只有一个注入器。您将使用一个注入器来创建侦听器,并使用一个注入器来创建代码 tested/analyzed.
如果你真的想要一个注入器(例如,如果你希望监听的注入器中的类型和监听器需要的类型是内聚的)那么你最好的选择是 AbstractModule 的 getProvider() 方法。所以,如果 MyTypeListener 需要 Foo 的实例,这就是 MyModule 的样子:
static class MyModule extends AbstractModule {
@Override protected void configure() {
TypeListener listener = new MyTypeListener(getProvider(Foo.class));
bindListener(Matchers.any(), listener);
}
}
如果您还没有使用过 getProvider()
,请注意,在构造注入器之前,您不能对提供程序调用 .get()
。只要您不从侦听器的构造函数的上下文中调用它,就可以了。
我有这种情况,我想注入一个 TypeListener
与依赖关系,但它永远不会工作,因为 TypeListener
用于实际执行注入。
我怎样才能完成这件事?有 guicey 方式吗?
备注:
- 我正在使用 Guice 4.0
MyManager
将在Guice::createInjector
之后使用。MyManager::registerType
和MyManager::use
都在Guice::createInjector
returns 之前独占调用。MyDependency
的存在表明MyManager
不能用new
实例化。Guice::createInjector
回来后我也会用
我创建了以下 SSCCE 来展示我的问题:
import com.google.inject.*;
import com.google.inject.matcher.*;
import com.google.inject.spi.*;
public class MyClass {
public static void main(String[] args) {
Guice.createInjector(new MyModule());
}
static class MyModule extends AbstractModule {
@Override protected void configure() {
TypeListener listener = new MyTypeListener();
requestInjection(listener);
bindListener(Matchers.any(), listener);
}
}
static class MyTypeListener implements TypeListener {
@Inject MyManager manager;
@Override public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
Class<?> rawType = type.getRawType();
manager.registerType(rawType);
encounter.register(new InjectionListener<I>() {
@Override public void afterInjection(I injectee) {
manager.use(rawType, injectee);
}
});
}
}
@Singleton static class MyManager {
@Inject MyManager(MyDependency dependency) { }
void registerType(Class<?> type) { }
void use(Class<?> type, Object injectee) { }
}
static class MyDependency { }
}
我认为至少在某些时候(在测试或代码分析中)类型侦听器与他们正在侦听的类型没有内聚性,因此没有理由只有一个注入器。您将使用一个注入器来创建侦听器,并使用一个注入器来创建代码 tested/analyzed.
如果你真的想要一个注入器(例如,如果你希望监听的注入器中的类型和监听器需要的类型是内聚的)那么你最好的选择是 AbstractModule 的 getProvider() 方法。所以,如果 MyTypeListener 需要 Foo 的实例,这就是 MyModule 的样子:
static class MyModule extends AbstractModule {
@Override protected void configure() {
TypeListener listener = new MyTypeListener(getProvider(Foo.class));
bindListener(Matchers.any(), listener);
}
}
如果您还没有使用过 getProvider()
,请注意,在构造注入器之前,您不能对提供程序调用 .get()
。只要您不从侦听器的构造函数的上下文中调用它,就可以了。