Использование Google Guice для добавления свойств Java - PullRequest
14 голосов
/ 19 марта 2012

Я хочу использовать Google Guice, чтобы сделать свойства доступными во всех классах моего приложения. Я определил модуль, который загружает и связывает файл свойств Test.properties .

Property1=TEST
Property2=25

пакет com.test;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

import com.google.inject.AbstractModule;
import com.google.inject.name.Names;

public class TestConfiguration extends AbstractModule {

    @Override
    protected void configure() {
    Properties properties = new Properties();
    try {
        properties.load(new FileReader("Test.properties"));
        Names.bindProperties(binder(), properties);
    } catch (FileNotFoundException e) {
        System.out.println("The configuration file Test.properties can not be found");
    } catch (IOException e) {
        System.out.println("I/O Exception during loading configuration");
    }

    }
}

Я использую основной класс, где создаю инжектор для ввода свойств.

package com.test;

import com.google.inject.Guice;
import com.google.inject.Injector;

public class Test {

    public static void main(String[] args) {
    TestConfiguration config = new TestConfiguration();
    Injector injector = Guice.createInjector(config);
    TestImpl test = injector.getInstance(TestImpl.class);
    }
}

package com.test;

import com.google.inject.Inject;
import com.google.inject.name.Named;

public class TestImpl {
    private final String property1;
    private final Integer property2;

        @Inject
        public TestImpl(@Named("Property1") String property1, @Named("Property2") Integer property2) {

        System.out.println("Hello World");
        this.property1 = property1;
        this.property2 = property2;

        System.out.println(property1);
        System.out.println(property2);

        }
     }

Теперь мой вопрос. Если мой TestImpl создает другие классы, в которые мне также нужно ввести свойства, и эти классы также должны ввести свойства, каков правильный способ сделать это?

  1. Передать инжектор всем подклассам и затем использовать injector.getInstance (...) для создания подклассов?

  2. Установить новый инжектор типа

    TestConfiguration config = new TestConfiguration();
    Injector injector = Guice.createInjector(config);
    TestImpl test = injector.getInstance(TestImpl.class);
    

во всех вложенных классах?

  1. Есть ли другой способ сделать свойства доступными во всех классах?

Ответы [ 5 ]

11 голосов
/ 04 апреля 2012

Передайте инжектор всем подклассам и затем используйте injector.getInstance (...) для создания подклассов?

нет, тем самым вы побеждаете цель шаблона внедрение зависимостей , а также связываете всю свою реализацию с Guice. Ваши реализации не должны вообще взаимодействовать с guice, кроме как через (теперь стандартизированные) аннотации.

Установить новый инжектор, например

TestConfiguration config = new TestConfiguration(); 
Injector injector = Guice.createInjector(config); 
TestImpl test = injector.getInstance(TestImpl.class); 

во всех вложенных классах?

нет, и это еще хуже, потому что у вас будет несколько инжекторов, следовательно, несколько контекстов, которые будут препятствовать правильному использованию областей .

В идеале, вы должны использовать инжектор только во время начальной загрузки вашего приложения. Конечно, способ его загрузки во многом будет зависеть от приложения.

Есть ли другой способ сделать свойства доступными во всех классы?

Свойства могут быть введены так же, как вы делали это для TestImpl. Если вы хотите, чтобы TestImpl использовал, скажем, сервис, которому также нужны некоторые свойства (или другие сервисы), просто позвольте Guice внедрить его в TestImpl. Guice позаботится обо всех экземплярах и проводках. Вы должны указывать Guice «как действовать», используя связыватель, когда Guice сам не может понять это:

public class TestImpl {
    private final String property1;
    private final Integer property2;
    private final IService service;


        @Inject
        public TestImpl(@Named("Property1") String property1, @Named("Property2") Integer property2, IService service) {
           this.property1 = property1;
           this.property2 = property2;
           this.service= service;
        }
    }
}
3 голосов
/ 24 января 2014

Библиотека «Регулятор» предоставляет функцию сопоставления конфигурации для ввода подсказок.Подход другой, но загрузка из файлов свойств доступна.

https://github.com/Netflix/governator/wiki/Configuration-Mapping

1 голос
/ 21 января 2016

Библиотека Конфигурация Guice может вводить для вас значения из файлов Properties или JSON в ваши службы.

Вы можете внедрить из файла application.properties к вашим услугам как:

@BindConfig(value = "application", syntax = PROPERTIES)
public class Service {

    @InjectConfig
    private int port;

    @InjectConfig
    private String url;

    @InjectConfig
    private Optional<Integer> timeout;
}

Вы должны просто установить модули ConfigurationModule

public class GuiceModule extends AbstractModule {
    @Override
    protected void configure() {
        install(ConfigurationModule.create());
        requestInjection(Service.class);
    }
}
1 голос
/ 07 апреля 2015

мой подход - guice-config guice-config

0 голосов
/ 22 марта 2012

"Теперь мой вопрос. Если мой TestImpl создает другие классы, в которые мне также нужно вводить свойства, и эти классы также должны вводить свойства, как правильно это сделать?"

Правило большого пальца:Избегайте использования "new" Если это не является абсолютно необходимым, не позволяйте вашему Impl Class "создавать другие классы".Вместо этого сообщите вашему TestImpl, что при создании с помощью guice в него должны быть введены необходимые экземпляры.

...