Guice:如何为一个类型获得多个@Provides?

use*_*922 5 java hibernate guice

我正在研究一个项目并尝试将两个不同的"数据服务"模块组合到一个Web应用程序中(目前,该应用程序是一个桌面Swing应用程序).

每个模块都有自己的Guice(私有)模块.每个Guice模块包含:

@Provides
@Inject
protected JPQLQuery provideJPQLQuery(EntityManager entityManager) {
    return new JPAQuery(entityManager);
}
Run Code Online (Sandbox Code Playgroud)

稍后将在从db查找内容的类的构造函数中使用它:

@Inject
public SomeClassThatLooksObjectsUpFromDatabase(Provider<JPQLQuery> queryProvider) {
    this.queryProvider = queryProvider;
}
Run Code Online (Sandbox Code Playgroud)

然后'queryProvider'可以执行查询.

现在,当只安装了一个Guice模块时,这样可以正常工作,但是一旦安装了这两个模块,我(可预见地)会收到此错误:

Unable to create binding for com.mysema.query.jpa.JPQLQuery.  It was already configured on one or more child injectors or private modules
bound at ServiceOneGuiceModule.provideJPQLQuery()
bound at ServiceTwoGuiceModule.provideJPQLQuery()
Run Code Online (Sandbox Code Playgroud)

现在,我理解为什么这个被破坏了 - 我说有两个类型为JPQLQuery的提供者,Guice不知道使用哪一个.

有什么方法可以让Guice将这些提供商分开吗?我想这样做是因为每个模块都有自己正确配置的Hibernate实体,每个实体都有自己独特的数据源(这个项目中有多个数据库).

理想情况下,它会涉及某种方式命名这些提供程序并按名称注入它们(例如我可以单独注入"ServiceOneJPQLQueryProvider"和"ServiceTwoJPQLQueryProvider"),但我还没有找到任何方法来实现这样的任何事情.

(我想一个替代方案是以某种方式配置Hibernate,因此它拥有它需要的所有不同的数据源,然后我可能只需要一个Provider用于我的查询,但这看起来比我上面描述的要多得多)

Ran*_*niz 5

看看绑定注释,他们习惯于解决你所遇到的问题.

他们建议使用@Named,因为它们是类型安全的,如果拼错它们会产生编译错误而不会产生运行时错误.

简而言之:

ServiceOne.java:

@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
public @interface ServiceOne {}
Run Code Online (Sandbox Code Playgroud)

ServiceTwo.java:

@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
public @interface ServiceTwo {}
Run Code Online (Sandbox Code Playgroud)

ServiceOneModule.java:

@Provides
@ServiceOne
@Inject
protected JPQLQuery provideJPQLQuery(EntityManager entityManager) {
    return new JPAQuery(entityManager);
}
Run Code Online (Sandbox Code Playgroud)

SomeClass.java:

@Inject
public SomeClassThatLooksObjectsUpFromDatabase(@ServiceOne Provider<JPQLQuery> queryProvider) {
    this.queryProvider = queryProvider;
}
Run Code Online (Sandbox Code Playgroud)