java – Can Guice可以根据参数自动创建不同类的实例吗?

前端之家收集整理的这篇文章主要介绍了java – Can Guice可以根据参数自动创建不同类的实例吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
标准对象工厂可能如下所示:
  1. interface I { ... }
  2. class A implements I { ... }
  3. class B implements I { ... }
  4.  
  5. class IFactory {
  6. I getI(int i) {
  7. switch (i) {
  8. case 1: return new A();
  9. default: return new B();
  10. }
  11. }
  12. }

是否可以设置绑定以便为我完成切换,即我所做的只是调用getInstance或者注入?我正在寻找辅助注射,但这似乎是不同的主题https://code.google.com/p/google-guice/wiki/AssistedInject

解决方法

听起来你正在寻找 MapBinder,这是 Multibindings功能的一部分.请注意,您仍然需要放入某种IFactory或其他工厂接口,因为getInstance不像getI那样接受参数,并且您仍然需要在某处建立从整数到类实现的映射.

MapBinder式

  1. class IModule extends AbstractModule {
  2. @Override public void configure() {
  3. MapBinder<Integer,I> myBinder =
  4. MapBinder.newMapBinder(binder(),Integer.class,I.class);
  5. myBinder.addBinding(1).to(A.class);
  6. // Add more here.
  7. }
  8. }
  9.  
  10. // You can even split the MapBinding across Modules,if you'd like.
  11. class SomeOtherModule extends AbstractModule {
  12. @Override public void configure() {
  13. // MapBinder.newMapBinder does not complain about duplicate bindings
  14. // as long as the keys are different.
  15. MapBinder<Integer,I.class);
  16. myBinder.addBinding(3).to(C.class);
  17. myBinder.addBinding(4).to(D.class);
  18. }
  19. }

配置有这些模块的注射器将提供可注射的Map< Integer,I>.有一切事物的实例;这里它将是一个从3到完全注入的A实例的三条目映射,从3到C实例,从4到D实例.这实际上是对您的switch示例的改进,它使用了new关键字,因此没有将任何依赖项注入A或B.

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

  1. class YourConsumer {
  2. @Inject Map<Integer,Provider<I>> iMap;
  3.  
  4. public void yourMethod(int iIndex) {
  5. // get an I implementor
  6. I i = iMap.get(iIndex).get();
  7. // ...
  8. }
  9. }

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

  1. class IFactory {
  2. @Inject Map<Integer,Provider<I>> iMap;
  3. @Inject Provider<B> defaultI; // Bound automatically for every Guice key
  4.  
  5. I getI(int i) {
  6. return iMap.containsKey(i) ? iMap.get(i).get() : defaultI.get();
  7. }
  8. }

更简单,工厂风格

如果上面看起来有点矫枉过正,请记住你可以inject an Injector并创建一个从键到实现的本地Map. (你也可以像我在这里一样使用ImmutableMap).

  1. class IFactory {
  2. @Inject Injector injector; // This is a bad idea,except for times like this
  3. @Inject Provider<B> defaultI;
  4. static final ImmutableMap<Integer,Class<? extends I>> map = ImmutableMap.of(
  5. 1,A.class,3,C.class,4,D.class);
  6.  
  7. I getI(int i) {
  8. return map.containsKey(i)
  9. ? injector.getInstance(map.get(i))
  10. : defaultI.get();
  11. }
  12. }

猜你在找的Java相关文章