使用Guice注入带注释的泛型类

时间:2015-09-17 14:14:20

标签: java generics guice

我试图注入相同通用类型的不同版本,到目前为止没有运气。我在AbstractModule实现中执行的绑定是:

   bind(new TypeLiteral<ConcurrentHashMap<String, Integer>>() {
}).annotatedWith(Names.named("name0")).toProvider(
    ConcurrentHashMap::new).in(Singleton.class);
   bind(new TypeLiteral<ConcurrentHashMap<String, Long>>() {
}).annotatedWith(Names.named("name1")).toProvider(
    ConcurrentHashMap::new).in(Singleton.class);
   bind(new TypeLiteral<ConcurrentHashMap<String, Boolean>>() {
}).annotatedWith(Names.named("name2")).toProvider(
    ConcurrentHashMap::new).in(Singleton.class);
   bind(new TypeLiteral<ConcurrentHashMap<String, Short>>() {
}).annotatedWith(Names.named("name3")).toProvider(
    ConcurrentHashMap::new).in(Singleton.class);

我尝试通过简单地使用:

来注射它们
@Inject @Named("name0") ConcurrentHashMap<String, Integer>;

等等。但是,我收到以下错误:

  

1)无法为其创建绑定   java.util.concurrent.ConcurrentHashMap<java.lang.String, java.lang.Integer>注释   @ com.google.inject.name.Named(值= NAME0)。它已经配置好了   在一个或多个儿童注射器或私人模块上

我做错了什么?谢谢!

2 个答案:

答案 0 :(得分:2)

代码很好,错误信息非常明确:检查您的子注射器和您的私人模块是否有@Named("name0") ConcurrentHashMap<String, Integer>的任何其他绑定。 Guice非常小心,不允许在同一个注入器中绑定相同的键,即使由于子注入器或私有模块而无法直接从父注入器访问绑定。

您可能还会考虑为

切换toProvider语法
bind(new TypeLiteral<ConcurrentHashMap<String, Integer>>() {
}).annotatedWith(Names.named("name0")).toProvider(
ConcurrentHashMap::new).in(Singleton.class);

更简单地使用to

bind(new TypeLiteral<ConcurrentHashMap<String, Integer>>() {})
   .annotatedWith(Names.named("name0"))
   .to(ConcurrentHashMap.class)
   .in(Singleton.class);

...部分是因为它更典型的Guice使用,部分是因为它可能允许Guice更多地允许重复绑定。 (Guice可能很难通过从ConcurrentHashMap::newProvider<ConcurrentHashMap>的Java 8转换来检测重复项。)但是,诊断重复绑定可能是一个更好的主意。

答案 1 :(得分:2)

我发现问题在于注射器本身。当我使用“常规”Guice注入器时(通过调用Guice.createInjector(new MyModule())一切正常。但是,我一直在使用netflix调控器注入器(通过调用LifecycleInjector.builder().withModules(new MyModule()).build().createInjector()),这似乎导致了问题。