Подтвердить что ты не робот

Как связать String с переменной в Guice?

Я новичок в Guice, и вот наивный вопрос. Я узнал, что мы можем привязать String к определенному значению с помощью:

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

Но что, если я хочу привязать String к любым возможным символам?

Или я думаю, что это можно описать следующим образом:

Как заменить "новый SomeClass (String strParameter)" на Guice?

4b9b3361

Ответ 1

Сначала вам нужно аннотировать конструктор для 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 с обязательной аннотацией.

Все это предполагает, что существует некоторое постоянное значение, которое вы можете определить во время создания модуля для String. Если значение не доступно во время создания модуля, вы можете использовать AssistedInject.

Ответ 2

Это может быть не по теме, но Guice упрощает настройку, чем писать явное привязку для каждой строки, в которой вы нуждаетесь. Для них может быть только файл конфигурации:

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

и voilà вся ваша конфигурация готова для инъекций:

@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

или слить информацию авторизации из другого источника в свойства, и вы настроены.

Ответ 3

Я нашел решение в FAQ для Guice:

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

Помимо определения аннотации и атрибута String в MyModule, мне нужно написать ниже строку, чтобы получить экземпляр SomeClass:

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

Но я помнил, что Injector.getInstance() не следует использовать, кроме корневого объекта, так есть ли лучший способ сделать это?