【问题标题】:More than one singleton instance in Guice injectorGuice 注入器中的多个单例实例
【发布时间】:2012-07-17 09:58:44
【问题描述】:

我们有一个 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>);

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

【问题讨论】:

    标签: dependency-injection guice


    【解决方案1】:

    您可以尝试使用 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);
        }
      }
    }
    

    附: 我是从头开始写的,所以可能无法编译,这只是一个想法。

    【讨论】:

    • 谢谢。您建议使用 InstancePool,这不是解决方案。我需要实例映射,因为实例之间存在差异,每次我需要注入特定实例时,我都需要该特定实例,而不是随机的。无论如何,谢谢你的回答。
    • @fiction:请编辑您的问题,以便包含此要求。
    【解决方案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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多