2016-08-01 3 views

ответ

0

В Guice вы должны аннотировать метод и сделать его необязательным. Затем вы просто назначаете значение по умолчанию. Если никакое свойство не будет введено, это будет значение по умолчанию.

Например:

public class TestModule3 extends AbstractModule { 

    @Override 
    protected void configure() { 

//  Properties p = new Properties(); 
//  p.setProperty("myValue", "12"); 
//  Names.bindProperties(binder(), p); // this binds the properties that usually come for a file 

     bind(Manager.class).to(ManagerImpl.class).in(Singleton.class); 
    } 

    public static interface Manager { 
     public void talk(); 
    } 

    public static class ManagerImpl implements Manager { 

     @Inject(optional = true) 
     @Named("myValue") 
     int test = 0; 

     @Override 
     public void talk() { 
      System.out.println(test); 
     } 
    } 

    public static void main(String[] args) { 

     Manager instance = Guice.createInjector(new TestModule3()).getInstance(Manager.class); 
     instance.talk(); 

    } 
} 

Это будет печатать "0" для вас, потому что я закомментирована связывания собственности. Если вы удалите комментарии, он свяжет значение 12 с типом myValue. Аннотации для инъекций заботятся об остальном.

Надежда, что помогает,

EDIT:

Как @TavianBarnes отметил, Guice 4+ имеет OptionalBinder. Я попробовал это для вашего использования и не мог заставить его работать из коробки.

Похоже, что OptionalBinding очень полезно для классов (фактических экземпляров), а не для свойств. Вот почему:

  1. Вы должны знать все свойства заранее и привязать их к своим значениям по умолчанию. Их легко забыть. Пример, показанный OP, также показывает, что он не знает, есть ли у него доступное свойство (на основе имени).

  2. По умолчанию реализация привязок свойств не работает в сочетании с необязательным привязкой.

Так как вы можете сделать эту работу, как это:

 OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, Names.named("myValue"))).setDefault() 
       .toInstance("777"); 

     Properties p = new Properties(); 
     p.setProperty("myValue", "12"); 

     // use enumeration to include the default properties 
     for (Enumeration<?> e = p.propertyNames(); e.hasMoreElements();) { 
      String propertyName = (String) e.nextElement(); 
      String value = p.getProperty(propertyName); 

      OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, Names.named(propertyName))).setBinding() 
        .toInstance(value); 

     } 

мне пришлось скопировать поименованый код и изменить его для поддержки дополнительных привязок.

В итоге:

  1. Я предпочел бы использовать опциональный = истинный флаг + значение по умолчанию в коде для свойств.

  2. Используйте необязательный привязку для реальных классов, которые могут быть необязательными.

Наконец, есть еще одна вещь, которую вы могли бы сделать - это мое решение в моем коде. У меня есть аналогичное требование (а не необязательные, но значения по умолчанию).

Я хочу:

  1. Bind мои свойства
  2. Проверьте мои свойства переменной
  3. Заменить переменную
  4. Если переменная не доступна набор по умолчанию

Apache предлагает удобную библиотеку для этого уже, которую я использую повторно. Вот как выглядят мои свойства:

myProperty=${ENV_VAR_NAME:-600} 

Это аннотация по умолчанию, как определить значение по умолчанию. Вышеупомянутое свойство говорит:

  1. Используйте переменную evnironment "ENV_VAR_NAME".
  2. Если "ENV_VAR_NAME" не установлен, то используется значение "600"

Затем я связать его следующим образом:

 InputStream resourceAsStream = getClass().getResourceAsStream(path); 
     if(resourceAsStream == null) { 
      throw new IllegalArgumentException("No property file found for path: " + path); 
     } 
     try { 
      p.load(resourceAsStream); 
      EnvironmentVariableSubstitutor envSubstitutor = new EnvironmentVariableSubstitutor(false); 
      Set<Object> keys = p.keySet(); 
      for(Object k : keys) { 
       String property = p.getProperty(k.toString()); 
       property = envSubstitutor.replace(property); 
       p.put(k, property); 
      } 

     } catch (IOException e) { 
      throw new IllegalStateException("Could not load properties", e); 
     } finally { 
      try { 
       resourceAsStream.close(); 
      } catch (IOException e) { 
       log.error("Could not close stream for resource " + path); 
      } 
     } 

     Names.bindProperties(binder(), p); 

Что делает этот код является:

  1. нагрузки свойства из файла ресурсов
  2. Используйте EnvironmentVariableSubstitutor для обработки значений свойств и перезаписывания результата. (см. цикл)
  3. , наконец, привяжите измененные свойства к их именам.

Они все решения я могу придумать в короткий срок :) дайте мне знать, если что-то неясно,

Edit 2:

есть некоторая информация о OptionalBindings и свойства + как обращаться значения по умолчанию в этом Google потоке, а также: https://groups.google.com/forum/#!topic/google-guice/7Ga79iU_sb0

Артур

+0

С Guice 4+, вы должны использовать 'OptionalBinder' вместо' @Inject (опционально = истина) ' –

+0

@TavianBarnes Спасибо! я не знал этого, скоро обновит свой пример. – pandaadb

+0

@TavianBarnes Я думаю, что OptionBinding не очень полезно для свойств, которые вы не знаете, существуют ли они. Я обновил ответ своими мыслями :) Неважно, хорошо знать об этом – pandaadb

Смежные вопросы