How to bind String to variable in Guice?

eric2323223 picture eric2323223 · Oct 14, 2009 · Viewed 34.3k times · Source

I'm new to Guice and here is a naive question. I learned that we could bind String to a particular value through:

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

But what if I want to bind String to any possible characters?

Or I think it could be described this way:

How can I replace "new SomeClass(String strParameter)" with Guice?

Answer

NamshubWriter picture NamshubWriter · Oct 19, 2009

You first need to annotate the constructor for SomeClass:

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

I prefer to use custom annotations, like this:

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

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

Then you need to provide a binding in your Module:

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

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

Then an time Guice creates SomeClass, it will inject the parameter. For instance, if SomeOtherClass depends on SomeClass:

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

Often, when you think you want to inject a String, you want to inject an object. For instance, if the String is a URL, I often inject a URI with a binding annotation.

This all assumes there is some constant value you can define at module creation time for the String. If the value isn't available at module creation time, you can use AssistedInject.