Создайте бин динамически, передавая «профиль» во время выполнения - PullRequest
0 голосов
/ 28 сентября 2018

Допустим, у меня есть следующие настройки

application-toyota.properties

model=prius
type=hybrid

application-chevy.properties

model=volt
type=electric

классы:

public class Car{

@Value("${model}")
private String model;
@Value("${type}")
private String type;

...setters & getters...
}

и

public class CarFactory{

private Car car;
public Car makeCar(String profile){

return car;
}

}

Есть ли способ заставить метод makeCar принять профиль, скажем «toyota», динамически построить объект Car при заполнении значений из соответствующего файла свойств (application-toyota.properties) в таком случае и вернуть действительный объект Car?

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Мне кажется, я понимаю, что вы пытаетесь сделать, но вы путаете терминологию.Если ваша цель состоит в том, чтобы создать единственное приложение, которое поддерживает один тип автомобиля, то ответ Марка - то, что вы собираетесь.Если, однако, вам нужна фабрика, которая создает несколько типов автомобилей с разными конфигурациями, для которых вы не знаете, какие они есть во время компиляции / запуска, вам нужно подойти к этой идее по-другому.

В этой версии у нас будет несколько «типов» автомобилей, определенных в профиле, поэтому у нас будет класс автомобиля POJO.

public class Car {

    private String model;
    private String type;

    public Car() {
    }

    public Car(String model, String type) {
        this.model = model;
        this.type = type;
    }
}

Тогда у нас будет ваш CarFactory только потому, чтоу нас есть несколько конфигураций для фабрики, мы будем обрабатывать их на карте.

public class CarFactory {

    Map<String, ConfiguredCarFactory> factories = new HashMap<>();

    public Car makeCar(String profile) {
        return getFactory(profile).makeCar();
    }

    private ConfiguredCarFactory getFactory(String profile) {
        ConfiguredCarFactory carFactory = factories.get(profile);
        if(carFactory == null) {
            carFactory = new ConfiguredCarFactory(profile);
            factories.put(profile, carFactory);
        }
        return carFactory;
    }
}

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

Тогда, наконец, у нас будет настроенная CarFactory, выполняющаяфактическое создание автомобиля, по профилю.

public class ConfiguredCarFactory {

    private final String profile;
    private String model;
    private String type;


    public ConfiguredCarFactory(String profile) {
        this.profile = profile;
        Properties prop = new Properties();
        File file = new File(profile);
        try(FileInputStream input = new FileInputStream(profile))  {
            prop.load(input);
            model = (String) prop.get("model");
            type = (String) prop.get("type");
        } catch (Exception e) {
            e.printStackTrace();
            model = "Generic";
            type = "Generic";
        }
    }

    public Car makeCar() {
        return new Car(model, type);
    }
}

Хотя это, безусловно, отвечает вашим требованиям, я не решаюсь сказать, что это то, что вы ищете.Предоставление неизвестного количества конфигураций автомобилей в качестве свойств менее идеально, чем, скажем, сохранение всех конфигураций автомобилей в базе данных и создание экземпляров в виде сущностей через JPA.Это гораздо более «динамично» и будет более точно следовать философии проектирования Spring, чем что-то относительно жесткое и требующее наличия файлов конфигурации на машине в дополнение к некоторому неизвестному вводу из источника файла.

0 голосов
/ 28 сентября 2018

Я думаю, вы должны уточнить вопрос больше.Я объясню

В Spring профили указываются в самом начале (обычно через параметры выполнения приложения, управляемого пружиной).

В этом примере не имеет смысла активироватьоба профиля одновременно, потому что они будут «конкурировать» за фактические значения свойств «модель» и «тип».

Из этого я заключаю, что вы активируете только один профиль.

Теперь, если профильскажем, «toyota» активна, значения для автомобильного объекта четко определены, поэтому вам даже не нужна фабрика автомобилей - Spring прочитает соответствующий файл свойств (в данном случае application-toyota.properties), разрешитзначения свойств и будут вводить правильные значения для автомобильного боба, который также приводится в движение пружиной.Конечно, то же самое можно сказать и о профиле "chev".

...