Guice注入器中有多个单例实例

时间:2012-07-17 09:58:44

标签: dependency-injection guice

我们有一个Jetty / Jersey应用程序。我们正在将其转换为使用Guice进行DI。问题:我们需要一个Singleton类的多个实例。 catch:实例数是从配置文件动态确定的。因此,我们无法对不同的实例使用注释。

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

但问题是我需要一些动态注释,而不是预定义注释。

2 个答案:

答案 0 :(得分: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);
    }
  }
}

P.S。 我是从脑子里写的,所以也许它不能编译,这只是一个想法。

答案 1 :(得分: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);
    }
}