2013-08-31 73 views
5

我一直在网上寻找关于喷油器启动问题的解释以及如何/何时使用createChildInjector(),但我无法找到清晰简洁的解释。注射器层次结构/儿童注射器解释?

这里是我的使用情况:

  • 我有我用注入一定的语境项的基础应用模块。该模块应该包含在每个喷油器实例中。
  • 我有一个搜索模块,它搜索数据库
  • 我有一个搜索模块,它搜索ElasticSearch。该类中的某些绑定应覆盖数据库搜索模块中提供的绑定。

例如,假设数据库搜索模块包括:

bind(PlaceSearch.class).to(HibernatePlaceSearch.class); 
bind(PersonSearch.class).to(HibernatePersonSearch.class); 

而且ElasticSearch模块包含:

bind(PersonSearch.class).to(PersonElasticSearch.class); 

有没有一种方法来创建一个包含PlaceSearch从结合注射器数据库搜索模块和ElasticSearch模块中的PersonSearch绑定,而不创建包含

的单独模块3210
bind(PlaceSearch.class).to(HibernatePlaceSearch.class); 
bind(PersonSearch.class).to(PersonElasticSearch.class); 

?这是Modules.override()的情况吗? createChildInjector的一个例子?提前致谢!

回答

2

这是一个完美的案例Modules.override()

大多数应用程序不应该使用儿童注射器。它们增加了很多配置的复杂性,并对角落案例有一些令人惊讶的行为。

+0

感谢您的回答。你能给我一个解释,究竟是一个小孩注射器是什么?或者指出一个很好的参考?我不确定我是否完全理解儿童注射器的概念。 – jcampos8782

+0

这个答案中的儿童注射器概念很好解释:http://stackoverflow.com/a/12774246/205866 – racc

4

Modules.override()不在Stage.PRODUCTION中工作。您应该使用PrivateModule,其中绑定仅在私有模块内有效/可见,因此您可以将不同的实现类绑定到相同的接口。然后,您可以将Private模块安装到父模块,但您必须明确地expose()所有要让其他模块可见的绑定。

Guice - Private Modules

比方说:

DatabaseSearchModule.java(延伸PrivateModule)

bind(PlaceSearch.class).annotatedWith(Names.named("dbSearch")).to(HibernatePlaceSearch.class); 
bind(PersonSearch.class).to(HibernatePersonSearch.class); 
expose(PlaceSearch.class).annotatedWith(Names.named("dbSearch")); 

EleasticSearchModule.java(延伸PrivateModule)

bind(PersonSearch.class).annotatedWith(Names.named("elastic")).to(PersonElasticSearch.class); 
expose(PersonSearch.class).annotatedWith(Names.named("elastic")); 
然后

那么你可以在一些家长抽象或servlet模块

MainModule.java

install(new DatabaseSearchModule()); 
install(new EleasticSearchModule()); 

bind(OtherClass.class); 

OtherClass安装。java的

@Inject @Named("elastic") 
private PlaceSearch elasticSearch; 
@Inject @Named("dbSearch") 
private PlaceSearch dbSearch; 

您可以使用Named注释,或者您可以创建非常优雅的自己的绑定Annotation

+0

这有助于。谢谢! – jcampos8782