Как настроить 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 заставляет среду не быть автоматически подключенной ...
Итак, после этого длинного объяснения, мои вопросы:
Это правильный способ решения этой проблемы?Если так, что не так с моей конфигурацией?Как я могу упростить настройку (если вообще)?Есть ли альтернативный механизм, который решит мою проблему?Спасибо за ваше время! :)