6

我一直在网上寻找有关注入器层次结构以及如何/何时使用 createChildInjector() 的解释,但我找不到清晰简洁的解释。

这是我的用例:

  • 我有一个基本应用程序模块,我用它来注入某些上下文项。这个模块应该包含在每个注入器实例中。
  • 我有一个搜索数据库的搜索模块
  • 我有一个搜索 ElasticSearch 的搜索模块。此类中的某些绑定应覆盖数据库搜索模块中提供的绑定。

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

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

ElasticSearch 模块包含:

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

有没有办法创建一个注入器,其中包括来自数据库搜索模块的 PlaceSearch 绑定和来自 ElasticSearch 模块的 PersonSearch 绑定,而无需创建包含

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

? 这是 Modules.override() 的情况吗?createChildInjector 的案例?提前谢谢!

4

2 回答 2

4

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

Guice - 私有模块

让我们说:

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"));

那么你可以将它安装在一些 Parent abstract 或 servlet 模块中

主模块.java

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

bind(OtherClass.class);

其他类.java

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

您可以使用Named注解,也可以创建非常优雅的自己的绑定注解

于 2013-09-02T09:27:54.193 回答
2

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

大多数应用程序不应使用子注射器。它们增加了很多配置复杂性,并且在极端情况下有一些令人惊讶的行为。

于 2013-08-31T20:36:01.297 回答