我正在学习 Google Guice。你知道如何实现“机器人腿”问题吗?让我用一个例子来解释这一点。
假设我有一个名为 的类Service
:
@Singleton
public class Service {
@Inject
Source source;
}
该接口Source
有两种实现:
public class SourceDatabase implements Source {
}
public class SourceFileSystem implements Source {
}
我的模块是这样实现的:
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(Service.class).asEagerSingleton();
}
}
好吧,我想知道这是否可能:
public class MainClass {
@Inject @SomeAnnotation("database")
Service serviceWithADatabaseSource;
@Inject @SomeAnnotation("file-system")
Service serviceWithAFileSystemSource;
}
是否存在一些让我这样做的注释或绑定,让我注释一个像 的成员serviceWithADatabaseSource
,这有助于 Guice 知道内部成员source
应该被注入SourceDatabase
实现?
编辑:感谢 Daniel Martin,在他的评论中为我们提供了此类问题的名称。
正如Guice Wiki 中所述,您需要安装两个PrivateModule,每个都为您公开一个带有正确注释的服务。
如果模块不是 PrivateModule 实例,则这些到 Source 和 Service 的绑定会相互冲突。然而,相反,每个绑定都继承了注入器的所有公共绑定,但只
@Named(...) Service
向外界公开。这样,相同的Service
实现可以注入相同的未注释Source
但返回不同的完全注入类型。另请注意,您将无法在 PrivateModules 之外请求
Source
orService
(没有注释),因为您尚未在任何非私有模块中建立绑定。这应该是预料之中的:PrivateModule 绑定不应与任何公共绑定冲突,并且如果不通过 PrivateModule 的公开绑定之一进入,Guice 将不知道返回哪个Source
或Service
返回哪个。最后,鉴于 Module 实例可以接受构造函数参数,将两个匿名内部 PrivateModules 提取到命名的等效项中可能是个好主意: