Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Guice多注释_Java_Guice - Fatal编程技术网

Java Guice多注释

Java Guice多注释,java,guice,Java,Guice,我有一个名为StatsStore的接口。我有这个商店的两个实现。一个名为InMemoryStatsStore和SqlStatsStore的内存和SQL实现。为了注入它们,我创建了两个注释@InMemoryStore和@SqlStore。注射方法如下: bind(StatsStore.class) .annotatedWith(InMemoryStore.class) .to(InMemoryStatsStore.class); bind(StatsStore.class)

我有一个名为
StatsStore
的接口。我有这个商店的两个实现。一个名为
InMemoryStatsStore
SqlStatsStore
的内存和SQL实现。为了注入它们,我创建了两个注释
@InMemoryStore
@SqlStore
。注射方法如下:

bind(StatsStore.class)
    .annotatedWith(InMemoryStore.class)
    .to(InMemoryStatsStore.class);

bind(StatsStore.class)
    .annotatedWith(SqlStore.class)
    .to(SqlStatsStore.class);   
现在我想添加一个新的注释层,以在
InMemoryStringStore
InMemoryNumberStore
之间进行分隔,但我不能向绑定行添加多个注释,例如,以下内容无法编译:

bind(StatsStore.class)
    .annotatedWith(InMemoryStore.class)
    .annotatedWith(NumberStoreAnnotation.class) // using named doesn't work as well
    .to(InMemoryNumberStore.class);  
我怎样才能添加多个注释而不使用一个命名的注释呢?添加的图层越多,注释就越复杂

我想到的另一个解决方案是注射两次:

bind(StatsStore.class)
    .annotatedWith(InMemoryStore.class)
    .to(InMemoryStatsStore.class);

 bind(InMemoryStatsStore.class)
    .annotatedWith(NumberStoreAnnotation.class)
    .to(InMemoryNumberStore.class);
谢谢大家

你:

@BindingAnnotation
告诉Guice这是一个绑定注释Guice将产生一个错误,如果有多个绑定注释应用于同一个成员


你可以使用命名绑定,或者你应该考虑重新设计你的解决方案。

正如Amit所说,你不能有一个以上的bdin注释适用于任何给定的注入。在内部,Guice的工作方式类似于

映射
,其中键可能是一个参数化类,带有可选的单个注释实例。但是,因为这些都是实例,所以欢迎您使用
命名的
工作方式

@Inject @InMemoryStore(NUMBER) StatsStore inMemoryNumberStore;
@Inject @SqlStore(STRING) StatsStore sqlStringStore;
// or
@Inject @Store(dataType=NUMBER, backend=SQL) sqlNumberStore;
注释必须具有这样定义的字段。(如果有一个元素名为
value
,则可以省略属性名。)定义了相等的注释

这对于
@提供了
,当您可以以注入注释的相同方式调用注释时,效果很好,但是如何为
name.named等实例创建工厂方法呢?为此,您需要执行以下操作之一:

  • ,具有每个属性的访问器以及
    equals
    hashCode
    的正确实现。请注意,
    hashCode
    契约是,但您可以从或类似的库中获得兼容的实现
  • 使用,它为任意子类提供
    equals
    hashCode
    实现
  • 使用或类似的代码生成器为您的兼容实现生成代码。熟悉这种类型的解决方案对于Android和其他反射速度较慢的内存受限环境特别有用,尽管这样的环境通常会阻止您使用Guice。(
    @Qualifier
    注释在其他与JSR-330兼容的依赖项注入框架(包括Dagger)中的工作方式相同。)

  • 如果以上内容看起来有点复杂,或者如果您想要比Guice基于映射的实现更复杂的逻辑,一种替代方法是添加一层您可以控制的间接寻址:

    public class StoreStore {
      @Inject Provider<InMemoryNumberStore> inMemoryNumberStoreProvider;
      // ...
      // You can also inject the Injector to call getInstance with a class literal.
    
      public StatsStore getStore(DataType dataType, Backend backend) {
        // This can also be a switch or any other sort of lookup, of course.
        if (dataType == NUMBER && backend == IN_MEMORY) {
          return inMemoryNumberStoreProvider.get();
        } // ...
      }
    }
    
    公共类存储{
    @在MemoryNumberStoreProvider中插入提供程序;
    // ...
    //您还可以注入注入器以使用类文本调用getInstance。
    公共StatsStore getStore(数据类型DataType,后端){
    //当然,这也可以是一个开关或任何其他类型的查找。
    if(数据类型==数字和后端==内存中){
    返回inMemoryNumberStoreProvider.get();
    } // ...
    }
    }
    
    我可以添加多个名称而不仅仅是一个长名称吗?如果可能的话,我想避免在内存中使用类似于
    states.\u tore.\u memory.number
    …的名称。感谢您的深入解释和解决方案。实际实现注释的一个很好的替代方法就是使用
    @Provides
    方法。@Tavian:是的!如上所述(“效果很好…”)。
    public class StoreStore {
      @Inject Provider<InMemoryNumberStore> inMemoryNumberStoreProvider;
      // ...
      // You can also inject the Injector to call getInstance with a class literal.
    
      public StatsStore getStore(DataType dataType, Backend backend) {
        // This can also be a switch or any other sort of lookup, of course.
        if (dataType == NUMBER && backend == IN_MEMORY) {
          return inMemoryNumberStoreProvider.get();
        } // ...
      }
    }