23

我是 Guice 的新手,这是一个幼稚的问题。我了解到我们可以通过以下方式将 String 绑定到特定值:

bind(String.class)
        .annotatedWith(Names.named("JDBC URL"))
        .toInstance("jdbc:mysql://localhost/pizza");

但是,如果我想将 String 绑定到任何可能的字符怎么办?

或者我认为可以这样描述:

如何用 Guice 替换“new SomeClass(String strParameter)”?

4

4 回答 4

44

您首先需要注释构造函数SomeClass

class SomeClass {
  @Inject
  SomeClass(@Named("JDBC URL") String jdbcUrl) {
    this.jdbcUrl = jdbcUrl;
  }
}

我更喜欢使用自定义注释,如下所示:

class SomeClass {
  @Inject
  SomeClass(@JdbcUrl String jdbcUrl) {
    this.jdbcUrl = jdbcUrl;
  }

  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.FIELD, ElementType.PARAMETER})
  @BindingAnnotation
  public @interface JdbcUrl {}
}

然后你需要在你的模块中提供一个绑定:

public class SomeModule extends AbstractModule {
  private final String jdbcUrl; // set in constructor

  protected void configure() {
    bindConstant().annotatedWith(SomeClass.JdbcUrl.class).to(jdbcUrl);
  }
}

然后 Guice 创建 SomeClass 时,它会注入参数。例如,如果 SomeOtherClass 依赖于 SomeClass:

class SomeOtherClass {
  @Inject
  SomeOtherClass(SomeClass someClass) {
    this.someClass = someClass;
  }

通常,当你想注入一个字符串时,你想注入一个对象。例如,如果 String 是一个 URL,我经常注入一个带有绑定注解的URI 。

这一切都假设您可以在模块创建时为字符串定义一些常量值。如果该值在模块创建时不可用,您可以使用AssistedInject

于 2009-10-19T16:02:53.733 回答
21

这可能是题外话,但 Guice 使配置比为您需要的每个 String 编写显式绑定要容易得多。你可以只为他们准备一个配置文件:

Properties configProps = Properties.load(getClass().getClassLoader().getResourceAsStream("myconfig.properties");
Names.bindProperties(binder(), configProps);

瞧,您的所有配置都已准备好注入:

@Provides // use this to have nice creation methods in modules
public Connection getDBConnection(@Named("dbConnection") String connectionStr,
                                  @Named("dbUser") String user,
                                  @Named("dbPw") String pw,) {
  return DriverManager.getConnection(connectionStr, user, pw);
}

现在只需在类路径的根目录下创建Java 属性文件 myconfig.properties

dbConnection = jdbc:mysql://localhost/test
dbUser = username
dbPw = password

或将来自其他来源的授权信息合并到属性中,然后您就设置好了。

于 2015-02-04T22:38:10.273 回答
2

我能够通过Named注释注入一个字符串。

@Provides
@Named("stage")
String stage() {
    return domain;
}

class SomeClass {
   @Inject
   @Named("stage")
   String stageName;
}
于 2019-11-01T00:30:43.037 回答
0

我在 Guice 的 FAQ 中找到了一个解决方案:

http://code.google.com/docreader/#p=google-guice&s=google-guice&t=FrequentlyAskedQuestions

除了在 MyModule 中定义一个注解和一个字符串属性之外,我还需要写下一行来获取 SomeClass 的一个实例:

SomeClass instance = Guice.createInjector(new MyModule("any string i like to use")).getInstance(SomeClass.class);

但我记得 Injector.getInstance() 除了根对象之外不应该使用,那么有没有更好的方法来做到这一点?

于 2009-10-14T15:23:21.543 回答