【发布时间】:2009-08-03 11:53:39
【问题描述】:
你能得到 2 个相同底层类型的单例实例吗?
这在 spring 中显然是微不足道的,因为它基于您附加范围的命名实例,但我在 guice 中看不到关于将类型绑定到实现类的等价物。请注意,我不想绑定到实例,因为相关实例通过 guice 注入了其他依赖项。
【问题讨论】:
标签: java dependency-injection guice
你能得到 2 个相同底层类型的单例实例吗?
这在 spring 中显然是微不足道的,因为它基于您附加范围的命名实例,但我在 guice 中看不到关于将类型绑定到实现类的等价物。请注意,我不想绑定到实例,因为相关实例通过 guice 注入了其他依赖项。
【问题讨论】:
标签: java dependency-injection guice
在 Guice 中也很容易!创建两个投标注释,例如 @One 和 @Two,然后
bind(MySingleton.class).annotatedWith(One.class).toInstance(new MySingleton());
bind(MySingleton.class).annotatedWith(Two.class).toInstance(new MySingleton());
然后
@Inject
public SomethingThatDependsOnSingletons(@One MySingleton s1,
@Two MySingleton t2) { ... }
【讨论】:
bind(MySingleton.class).annotatedWith(One.class).to(MySingleton.class).in(Singleton.class); bind(MySingleton.class).annotatedWith(Two.class).to(MySingleton.class).in(Singleton.class);
我想补充 Marcin 的回答,补充说您不必限制自己在这种情况下使用 toInstance() 或提供程序方法。
以下内容同样有效:
bind(Person.class).annotatedWith(Driver.class).to(MartyMcFly.class).in(Singleton.class);
bind(Person.class).annotatedWith(Inventor.class).to(DocBrown.class).in(Singleton.class);
[...]
@Inject
public BackToTheFuture(@Driver Person marty, @Inventor Person doc) { ... }
Guice 在实例化 MartyMcFly 和 DocBrown 类时会像往常一样注入依赖项。
请注意,当您想绑定多个相同类型的单例时,它也可以工作:
bind(Person.class).annotatedWith(Driver.class).to(Person.class).in(Singleton.class);
bind(Person.class).annotatedWith(Inventor.class).to(Person.class).in(Singleton.class);
为此,您必须确保 Person 未绑定在 Singleton 范围内,无论是明确地在 Guice 模块中还是使用 @Singleton 注释。更多详情请见this Gist。
编辑: 我作为示例给出的示例代码来自Guice Grapher Test。 查看 Guice 测试是更好地了解如何使用 API 的好方法(这也适用于每个具有良好单元测试的项目)。
【讨论】:
bind(MySingleton.class).annotatedWith(One.class).to(MySingleton.class).in(Singleton.class); bind(MySingleton.class).annotatedWith(Two.class).to(MySingleton.class).in(Singleton.class);
MartyMcFly 和 DocBrown 都扩展了 Person 类,@Driver 和 @Inventor 是 Binding Annotation 接口。 Guice FAQ 还显示了Private Modules solution,例如BackToTheFuture 类需要具有特定类型而不是基本类型(即BackToTheFuture(@Driver MaryMcFly driver,...))。