如何将特定参数绑定到自定义注释的实例?

时间:2011-07-04 12:43:51

标签: java guice

如何使用Guice进行以下工作?

// The Guice Module configuration
void configure() {
  // The following won't compile because HelpTopicId is abstract.
  // What do I do instead?
  bind(new TypeLiteral<String>(){}).
      annotatedWith(new HelpTopicId("A")).toInstance("1");
  bind(new TypeLiteral<String>(){}).
      annotatedWith(new HelpTopicId("B")).toInstance("2");
}

public @interface HelpTopicId {
  public String helpTopicName();
}

public class Foo {
  public Foo(@HelpTopicId("A") String helpTopicId) {
    // I expect 1 and not 2 here because the actual parameter to @HelpTopicId is "A"
    assertEquals(1, helpTopicId);
  }
}

2 个答案:

答案 0 :(得分:1)

最简单的方法可能是使用@Provides方法:

@Provides @HelpTopicId("A")
protected String provideA() {
  return "1";
}

或者,您可以创建HelpTopicId注释/接口的可实例化实现,类似于Names.named的实现(请参阅NamedImpl)。请注意,对于注释实现hashCode()之类的内容有一些特殊规则... NamedImpl遵循这些规则。

另外,使用new TypeLiteral<String>(){}是浪费的...... String.class可以代替它使用。此外,对于Stringint等,您通常应使用bindConstant()代替bind(String.class)。它更简单,要求您提供绑定注释,并且仅限于基元,String s,Class文字和enum s。

答案 1 :(得分:0)

构造函数Foo(String)必须使用@Inject进行注释。

您应该尝试使用Guice HelpTopicId注释,而不是使用自己的Named注释。

void configure() {
  bind(new TypeLiteral<String>(){}).annotatedWith(Names.named("A")).toInstance("1");
  bind(new TypeLiteral<String>(){}).annotatedWith(Names.named("B")).toInstance("2");
}

public class Foo {
  @Injected
  public Foo(@Named("A") String helpTopicId) {
    assertEquals("1", helpTopicId);
  }
}

如果您想推出自己的@Named接口实现,请查看包com.google.inject.name中的Guice实现。