注入一个 TypeListener

Inject a TypeListener

我有这种情况,我想注入一个 TypeListener 与依赖关系,但它永远不会工作,因为 TypeListener 用于实际执行注入。

我怎样才能完成这件事?有 guicey 方式吗?

备注:

我创建了以下 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()。只要您不从侦听器的构造函数的上下文中调用它,就可以了。