2

コンポーネントの 1 つに 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);
   }

}

このデザインについてどう思いますか? これに関する他のアイデアはありますか?(非管理オブジェクトから管理 Bean にアクセスする)

4

1 に答える 1

6

基本的に、探しているパターンは「静的インジェクションの要求」と呼ばれ、専用のBinderメソッドがあります。それを理解すると、コードはGuicedocsのこの例のようになります。

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);
  }
}

いくつかの注意:

  • フィールドをに設定することはprivateできますが、これは、Guiceのプライベートフィールドアクセスの魔法がなければ、テスト(または将来のGuice以外の使用)でフィールドを設定できないことを意味することに注意してください。インジェクトされたフィールドを使用する場合、多くの場合、それらをパッケージプライベートにしてから、テストを同じパッケージに入れます。

  • 静的インジェクションは、一般的に、Guiceに移行する場合、または変更できない他のコードを使用する場合にのみ推奨するものと見なされます。可能であれば、グローバル状態を回避するようにしてください。これは、FooBeanデータのみを作成し、インジェクトを作成することを意味する場合でも同様FooBeanServiceです。

  • 好きな場所に注入できますが、代わりにInjector注入するだけの方がテストしやすい場合があります。実行時まで必要なタイプがわからない場合にProvider<LookupService>のみ、を注入します。たとえば、インスタンスを取得するためにクラスリテラルをインジェクターに渡すことによってを使用して実装する場合です。InjectorLookupService.lookup(...)Injector

  • 実際、ここから言うのは難しいですが、Guiceが依存性注入で解決する問題の正確なタイプを解決するServiceLocatorパターンILookupとよく似ているようです。その場合は、Guiceを使用するようにILookupを書き直すことをお勧めします。への呼び出しを削除し、代わりにとの一致するペアを作成します。LookupService.instance().lookup(Foo.class)@Inject static Provider<Foo> fooProviderrequestStaticInjection(FooUser.class)

お役に立てば幸いです。

于 2012-10-31T03:08:19.807 に答える