0

Jetty/Jersey アプリケーションを取得しました。Guice for DI を使用するように変換しています。問題: Singleton クラスの複数のインスタンスが必要です。キャッチ: インスタンスの数は、構成ファイルから動的に決定されます。したがって、異なるインスタンスに注釈を使用することはできません。

 final InjectedClass instance = injector.getInstance(InjectedClass.class);

これは、インジェクターの標準構文です。次のようなものが必要です

 final String key = getKey();
 final InjectedClass instance = injector.getInstance(InjectedClass.class, key);

Guice からインスタンスを取得する方法がありますKey.class

 final InjectedClass instance = injector.getInstance(Key.get(InjectedClass.class, <Annotation>);

しかし、問題は、事前定義されたものではなく、動的な注釈が必要なことです。

4

2 に答える 2

2

これは、ファクトリを作成することで解決できます。私の例では、マルチバインディングと呼ばれるguice拡張機能を使用しまし

interface InjectedClassFactory {
    public InjectedClass get(String key);
}

class InjectedClass {}

class InjectedClassFactoryImpl implements InjectedClassFactory{
    private final Map<String, InjectedClass> instances;

    @Inject
    InjectedClassFactoryImpl(Map<String, InjectedClass> instances) {
        this.instances = instances;
    }

    @Override
    public InjectedClass get(String key) {
        return instances.get(key);
    }
}

class MyModule extends AbstractModule {

    @Override
    protected void configure() {
        MapBinder<String, InjectedClass> mapBinder =
                MapBinder.newMapBinder(binder(), String.class, InjectedClass.class);

        //read you config file and retrieve the keys
        mapBinder.addBinding("key1").to(InjectedClass.class).in(Singleton.class);
        mapBinder.addBinding("key2").to(InjectedClass.class).in(Singleton.class);
    }
}
于 2012-07-17T14:35:22.343 に答える
2

Provider、または作成済みのすべてのインスタンスのマップを持つ @Provides メソッドを使用することができます。インスタンスの数が構成ファイルで定義された数に達すると、新しいインスタンスは作成されず、マップから古いインスタンスが返されます。

たとえば、このようなものがあなたを助けることができます。

public class MyObjectProvider implements Provider<MyObject> {
  private final Injector inj;
  private int counter;
  private final int maxNum = 5;
  private List<MyObject> myObjPool = new ArrayList<MyObject>();

  @Inject
  public MyObjectProvider(Injector inj) {
    this.connection = connection;
  }

  public MyObject get() {
    counter = counter+1%maxNum;
    if(myObjPool.size()=<maxNum) {
      MyObject myobj = inj.getInstance(MyObject.class);
      myObjPool.add(myobj);
      return myobj;
    } else {
       return myObjPool.get(counter);
    }
  }
}

PS私は頭からこれを書いたので、コンパイルされないかもしれません。これは単なるアイデアです。

于 2012-07-17T11:20:55.760 に答える