当前位置: 首页 > 面试题库 >

Guice可以基于参数自动创建不同类的实例吗?

卢毅
2023-03-14
问题内容

标准对象工厂可能如下所示:

interface I { ... }
class A implements I { ... }
class B implements I { ... }

class IFactory {
    I getI(int i) {
        switch (i) {
        case 1: return new A();
        default: return new B();
        }
    }
}

是否可以设置绑定以便为我完成切换,即我要做的就是调用getInstance或inject?我当时在看辅助注射,但这似乎是另外一个话题:https : //code.google.com/p/google-
guice/wiki/AssistedInject


问题答案:

听起来您正在寻找MapBinder,这是多重绑定功能的一部分。请注意,您仍然需要放入某种IFactory工厂接口或其他工厂接口,因为getInstance它所采用的参数getI并不像您所使用的那样,并且您仍然需要在
某个地方 建立从整数到类实现的映射。

MapBinder样式

class IModule extends AbstractModule {
  @Override public void configure() {
    MapBinder<Integer, I> myBinder =
        MapBinder.newMapBinder(binder(), Integer.class, I.class);
    myBinder.addBinding(1).to(A.class);
    // Add more here.
  }
}

// You can even split the MapBinding across Modules, if you'd like.
class SomeOtherModule extends AbstractModule {
  @Override public void configure() {
    // MapBinder.newMapBinder does not complain about duplicate bindings
    // as long as the keys are different.
    MapBinder<Integer, I> myBinder =
        MapBinder.newMapBinder(binder(), Integer.class, I.class);
    myBinder.addBinding(3).to(C.class);
    myBinder.addBinding(4).to(D.class);
  }
}

配置有这些模块的注入器将提供Map<Integer, I>具有所有绑定实例的注入器。这里是从1到完全注入A实例,从3到C实例以及从4到D实例的三项映射。实际上,这是对您的switch示例的改进,该示例使用了new关键字,因此没有向Aor
注入任何依赖项B

对于不会创建太多浪费实例的更好选择,请注入Map<Integer, Provider<I>>MapBinder也自动提供的。像这样使用它:

class YourConsumer {
  @Inject Map<Integer, Provider<I>> iMap;

  public void yourMethod(int iIndex) {
    // get an I implementor
    I i = iMap.get(iIndex).get();
    // ...
  }
}

但是,要提供一种“默认”实现(和不透明的接口),您需要在MapBinder地图顶部实现自己的简短包装:

class IFactory {
  @Inject Map<Integer, Provider<I>> iMap;
  @Inject Provider<B> defaultI; // Bound automatically for every Guice key

  I getI(int i) {
    return iMap.containsKey(i) ? iMap.get(i).get() : defaultI.get();
  }
}

更简单的工厂风格

如果以上内容看起来有些矫kill过正,请记住您可以注入Injector并创建一个Map从密钥到实现的本地方法。(您也可以ImmutableMap像在这里一样使用)。

class IFactory {
  @Inject Injector injector; // This is a bad idea, except for times like this
  @Inject Provider<B> defaultI;
  static final ImmutableMap<Integer, Class<? extends I>> map = ImmutableMap.of(
      1, A.class,
      3, C.class,
      4, D.class);

  I getI(int i) {
    return map.containsKey(i)
        ? injector.getInstance(map.get(i))
        : defaultI.get();
  }
}


 类似资料:
  • 标准对象工厂可能如下所示: 是否可以设置绑定以便为我完成切换,即我所做的只是调用 getInstance 或注入?我正在研究辅助注射,但这似乎是不同的主题:https://code.google.com/p/google-guice/wiki/AssistedInject

  • 我有Java接口类。 我有另一个spec builder方法: 以上规范可用于创建客户端: 可用于调用下游客户端获取数据: 我创建了以下客户端规范静态映射:“ContentType”->DownstreamClientSpec 现在我有了一个处理程序方法: 除了contentType的switch语句和特定的客户端创建逻辑之外,我如何基于contentType获得客户端?使用Guice动态绑定特定

  • 对不起,如果这是一个微不足道的问题,我是新的指南。假设我有下面这个类: 然后在其他地方我想做: 我希望有两个“MyClass”实例,一个名为“foo ”,一个名为“bar ”(也就是说,它们中的每一个都有一个不同的依赖实例)。我如何将这两个实例添加到我的注入器中,如何用“injector.getInstance”检索它们中的每一个? 我不想为每个可能的依赖项创建一个“MyClass”的子类。 谢谢

  • 问题内容: 我正在尝试使函数采用可扩展的多个类之一,并在其Class中返回该对象的新实例,而不是的新实例。 我确定这是一个常见问题。有没有好的例子? 我从未使用过一个类作为输入参数,只使用了一个类的成员。根据我的搜索,这应该可行吗? 问题答案: 您是将对象作为参数传递还是作为的子类传递? 在这两种情况下,解决方案都几乎相同,您可以在Class对象上使用newInstance方法。 如果需要构造函数

  • 有什么方法可以为我创建的类使用自动装箱吗?例如,我有的子类。 现在,< code > UnsignedInteger I = new UnsignedInteger(88);工作得非常好,但是有什么方法可以让这个编译:< code > UnsignedInteger i = 88?对我来说不会。提前感谢!

  • 问题内容: 我有以下实体类(在Groovy中): and my persistence.xml: and the script: 数据库Icarus存在,但当前没有表。我希望Hibernate基于实体类自动创建和/或更新表。我将如何完成? 问题答案: 我不知道离开前线是否会有所作为。 该参考表明,它应该是 值为将会在创建时创建表,并保持它们不变。 值为会创建你的表,然后在关闭sessionFact