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

您可以尝试使用 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 回答
2

您可以通过创建工厂来解决此问题。在我的示例中,我使用了名为multibindings的 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 回答