Guice - 根据封闭类绑定不同的实例

时间:2014-02-04 14:12:41

标签: java guice

是否可以根据封闭类绑定Named实例?例如:在下面的示例中,A类和B类将获得DataStore实例注入。但是,我需要将主存储作为StoreA,将辅助存储作为StoreB放在A类的作用域/上下文中,而将主存储作为StoreC,将辅助存储作为StoreD放在B类的作用域/上下文中。如何实现?

class A {
   @Inject
   public A(DataStore dataStore) {
      ... 
   }
}

class B {
   @Inject
   public B(DataStore dataStore) {
      ... 
   }
}

class DataStore {
   @Inject
   public A(@Named("primary") Store primaryStore, @Named("secondary") Store store) {
      ... 
   }
}

bind(Store.class).annotatedWith(Names.named("primary")).to(StoreA.class);//for class A
bind(Store.class).annotatedWith(Names.named("secondary")).to(StoreB.class);//for class A
bind(Store.class).annotatedWith(Names.named("primary")).to(StoreC.class);//for class B
bind(Store.class).annotatedWith(Names.named("secondary")).to(StoreD.class);//for class B

1 个答案:

答案 0 :(得分:1)

这有时被称为"robot legs" problem,就像建造一个腿相同但左脚和右脚不同的机器人。每个腿绑定脚,但脚请求取决于腿请求。在您的情况下,每个DataStore都绑定到主存储和辅助存储,但哪些存储依赖于所请求的DataStore。

Guice注入的实例不能直接根据其目标(similar feature was rejected)进行绑定,但as mentioned in the FAQ可以使用PrivateModule来创建类似的效果。

install(new PrivateModule() {
  @Override public void configure() {
    bind(Store.class).annotatedWith(Names.named("primary")).to(StoreA.class);
    bind(Store.class).annotatedWith(Names.named("secondary")).to(StoreB.class);
    expose(A.class);
  }
});
install(new PrivateModule() {
  @Override public void configure() {
    bind(Store.class).annotatedWith(Names.named("primary")).to(StoreC.class);
    bind(Store.class).annotatedWith(Names.named("secondary")).to(StoreD.class);
    expose(B.class);
  }
});

因此,在@Named("primary") StoreA(或其依赖项)之外无法访问B,但这是有道理的;您永远不会定义一般Store,但AB每个都有他们需要的私有绑定。

(免责声明:我没有机会对此进行测试,因此可能需要改进。)