Как настроить Spring для частичного и необязательного переопределения свойств?

Я хотел бы иметь настройку свойств, которая может в определенных средах переопределять определенные свойства. Например, наши свойства JDBC по умолчанию для dev:

db.driverClassName = com.mysql.jdbc.Driverdb.url = JDBC: MySQL: // локальный: 3306 / ourdbdb.username = кореньdb.password =

Проблема в том, что некоторые наши разработчики хотели бы иметь другое имя пользователя / пароль в БД или, возможно, даже не локально размещенную БД. То же самое верно для нашей конфигурации rabbitMQ, которая в настоящее время использует аналогичную настройку localhost, guest / guest. Возможность переопределять свойства определенных элементов этой конфигурации для каждого разработчика позволит нам перенести большую часть требований к инфраструктуре / установке для сборки программного обеспечения с локального компьютера на выделенные серверы.

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

class Main_PropertyTest {
    public static void main(String[] args) {
        String environment = System.getenv("APPLICATION_ENVIRONMENT"); // Environment, for example: "dev"
        String subEnvironment = System.getenv("APPLICATION_SUB_ENVIRONMENT"); // Developer name, for example: "joe.bloggs"
        System.setProperty("spring.profiles.active", environment);
        System.setProperty("spring.profiles.sub", subEnvironment);

        try(AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PropertyTestConfiguration.class)) {
            Main_PropertyTest main = context.getBean(Main_PropertyTest.class);
            main.printProperty();
        }
    }

    private final String property;

    public Main_PropertyTest(String property) {
        this.property = property;
    }

    public void printProperty() {
        System.out.println("And the property is: '" + property + "'.");
    }
}

И моя конфигурация:

@Configuration
public class PropertyTestConfiguration {
    @Bean
    public static PropertySourcesPlaceholderConfigurer primaryPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        propertySourcesPlaceholderConfigurer.setLocation(new ClassPathResource(System.getProperty("spring.profiles.active") + ".main.properties"));
        return propertySourcesPlaceholderConfigurer;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer secondaryPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        propertySourcesPlaceholderConfigurer.setLocation(new ClassPathResource(System.getProperty("spring.profiles.sub") + ".main.properties"));
        propertySourcesPlaceholderConfigurer.setIgnoreResourceNotFound(true);
        propertySourcesPlaceholderConfigurer.setIgnoreResourceNotFound(true);
        propertySourcesPlaceholderConfigurer.setOrder(-1);
        return propertySourcesPlaceholderConfigurer;
    }

    @Bean
    public Main_PropertyTest main_PropertyTest(@Value("${main.property}") String property) {
        Main_PropertyTest main_PropertyTest = new Main_PropertyTest(property);
        return main_PropertyTest;
    }
}

И для полноты, мои dev.main.properties и test.main.properties:

main.property=dev

main.property=test

Основная проблема заключается в том, что я получаю исключение из незаконного аргумента. Насколько я могу судить, то, что я написал, должно быть javaconfig-эквивалентом этого метода:http://taidevcouk.wordpress.com/2013/07/04/overriding-a-packaged-spring-application-properties-file-via-an-external-file/ К сожалению, я получаю следующую ошибку: java.lang.IllegalArgumentException: не удалось разрешить заполнитель 'main.property» в строковом значении$ {Main.property}», Обратите внимание, что мне также нужно позаботиться о случае, когда нет подпространства, и это тот случай, с которого я начал (хотя я получаю ту же ошибку, даже если существуют оба файла). Если я удаляю bean-компонент, который устанавливает вторую правильную sourceplaceconfigurer, то все работает нормально (я имею в виду, что dev.main.properties загружен и "И это свойство:DEV «. распечатан).

Вторая проблема заключается в том, что код неВыглядит отлично, и каждому слою системы понадобятся два PSPC 'с настройками, чтобы они могли получить доступ к этим свойствам. Кроме того, это требует много ручных вызовов System.getProperty (), так как я не могt передать $ {spring.profiles.active} в PSPC.setLocation ();

Замечания: Я пробовал @PropertySources ({primaryproperties, primaryProperties}), но это не удалось, так как не существует virtualProperties. Я также попробовал среду @Autowired Environment; и получая свойства от этого, но вторичный PSPC заставляет среду не быть автоматически подключенной ...

Итак, после этого длинного объяснения, мои вопросы:

Это правильный способ решения этой проблемы?Если так, что не так с моей конфигурацией?Как я могу упростить настройку (если вообще)?Есть ли альтернативный механизм, который решит мою проблему?

Спасибо за ваше время! :)

Ответы на вопрос(2)

Ваш ответ на вопрос