Guice的实例方法

sol*_*l25 2 dependency-injection instance guice

我想为其中一个组件使用Guice的静态实例方法(非托管bean应该能够访问此类).我创建了这样的东西:

public class LookupService {

   @Inject
   private static Provider<Injector> injector = null;

   private final ILookup<IWS> lookup;

   @Inject
   public LookupService(ILookup<IWS> lookup) {
      this.lookup = lookup;
   }

   public static LookupService instance() {
     return injector.get().getInstance(LookupService.class);
   }

   public <T extends IWS> T lookup(Class<T> localInterface) {
      return lookup.lookup(localInterface);
   }
Run Code Online (Sandbox Code Playgroud)

}

你怎么看待这个设计?关于这个的任何其他想法?(从非托管对象访问托管bean)

Jef*_*ica 6

基本上,您正在寻找的模式称为"请求静态注入",并且有一个专门用于它Binder方法.一旦你失败了,你的代码看起来很像Guice文档中的这个例子.

public class MainModule extends AbstractModule {
  @Override public void configure() {
    requestStaticInjection(LookupService.class);
  }
}

public class LookupService {

  /** This will be set as soon as the injector is created. */
  @Inject
  static Provider<LookupService> provider = null;

  private final ILookup<IWS> lookup;

  @Inject
  public LookupService(ILookup<IWS> lookup) {
    this.lookup = lookup;
  }

  public static LookupService instance() {
    return provider.get();
  }

  public <T extends IWS> T lookup(Class<T> localInterface) {
    return lookup.lookup(localInterface);
  }
}
Run Code Online (Sandbox Code Playgroud)

几点说明:

  • 虽然您仍然可以设置您的字段private,但请记住,这意味着如果没有Guice的私有字段访问魔法,您无法在测试中(或在将来的非Guice用法中)设置它.当使用注入字段时,我们经常将它们打包为私有,然后将测试放在同一个包中.

  • 静态注入通常被视为只有在迁移到Guice时才能认可,或者当您使用其他无法更改的代码时.在可能的情况下,尽量避免全局状态 - 即使这意味着FooBean只生成数据并创建注入FooBeanService.

  • 即使你可以在Injector任何你想要的地方注入,你可能会发现如果你只是注入一个更容易测试Provider<LookupService>.只有注入的Injector,如果你不知道你要什么类型的需要,直到运行时-例如,如果实现LookupService.lookup(...)使用Injector由类文字传递到喷油器获得一个实例.

  • 事实上,从这里很难说,但ILookup似乎很像服务定位器模式,它解决了Guice通过依赖注入解决的确切类型的问题!如果是这种情况,你也可以重写ILookup来使用Guice:只需删除调用,LookupService.instance().lookup(Foo.class)然后创建一对匹配的@Inject static Provider<Foo> fooProviderrequestStaticInjection(FooUser.class).

希望有所帮助!