我们有一个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>);
但问题是我需要一些动态注释,而不是预定义注释。
答案 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);
}
}