Поместите application.properties в папку окружения в ресурсах
Я пишу весеннее загрузочное приложение с тремя средами - локальная, док-станция и рабочая среда. Я хотел бы, чтобы application.properties и несколько других файлов (database.properties и т. Д.) Были выбраны из следующей структуры папок внутри src / main / resources:
src/main/resources
- local
- application.properties
- database.properties
- dock
- application.properties
- database.properties
- production
- application.properties
- database.properties
- application.properties
Я использую Maven для создания своего приложения. В профиле Maven я сделал следующую конфигурацию для профилей:
<profiles>
<!--Local machine configuration-->
<profile>
<id>local</id>
<properties>
<spring.profiles.active>local</spring.profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<resources>
<resource>
<directory>src/main/resources/local</directory>
<targetPath>WEB-INF/classes</targetPath>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<resource>
<directory>src/main/resources/local</directory>
<targetPath>WEB-INF/classes</targetPath>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<!--Staging docker configuration-->
<profile>
<id>dock</id>
<properties>
<spring.profiles.active>dock</spring.profiles.active>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<resource>
<directory>src/main/resources/dock</directory>
<targetPath>WEB-INF/classes</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<!--Production configuration-->
<profile>
<id>production</id>
<properties>
<spring.profiles.active>production</spring.profiles.active>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<resource>
<directory>src/main/resources/production</directory>
<targetPath>WEB-INF/classes</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<finalName>${project.warname}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
В моем основном application.properties я сделал следующую конфигурацию:
spring.profiles.active=@spring.profiles.active@
Когда я запускаю проект, используя mvn spring-boot: run, загружается правильный профиль, но переменные внутри папки application.properties не обнаруживаются Spring. Например, у каждого из моих внутренних application.properties есть переменная, подобная этой:
my.var=This is production.
который я пытаюсь загрузить как
@Value("${my.var}")
private String data;
Я получаю следующее исключение:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'statusController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'my.var' in value "${my.var}"
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at com.onedirect.onedirectemailpushservice.OnedirectEmailPushServiceApplication.main(OnedirectEmailPushServiceApplication.java:10) [classes/:na]
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'my.var' in value "${my.var}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:236) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:172) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:831) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1086) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
... 17 common frames omitted
Я что-то здесь упускаю? Что мне нужно сделать, чтобы сделать эту работу?
PS: я знаю вариант использования application-{env}.properties, который поддерживается весенней загрузкой из коробки, но не хочу его использовать.
1 ответ
Если вашим основным ограничением является структура каталогов, которой вы должны следовать, то вы всегда можете построить свой проект с заданной структурой проекта и использовать spring.config.location
свойство среды для настройки расположения файлов свойств, которые вы хотите загрузить. Например:
java -jar my-app.jar --spring.config.location=classpath:local/application.properties,classpath:local/database.properties
Это также рекомендуемый подход в соответствии с документацией по внешней конфигурации:
Если тебе не нравится
application.properties
в качестве имени файла конфигурации вы можете переключиться на другое, указавspring.config.name
свойство окружающей среды. Вы также можете обратиться к явному местоположению, используяspring.config.location
свойство среды (разделенный запятыми список каталогов или путей к файлам).
Преимущество использования этого заключается в том, что вы можете предоставить несколько файлов свойств, разделяя их запятой. Это позволяет вам загружать ваши application.properties
, database.properties
, redis.properties
...
Это также позволяет вам удалить конфигурацию Maven, которую вы написали, чтобы изменить ваш путь к классам для каждой среды. Обычно вы не хотите создавать новый JAR-файл для конкретной среды, потому что это означает, что вы в основном создаете новый, непроверенный JAR-файл для производственной среды.
В качестве альтернативы вы можете использовать профили, чтобы убрать это. Например, переименуйте файлы свойств в:
application-local.properties
application-local-database.properties
application-local-redis.properties
- ...
И запустите ваше приложение с профилями local, local-database и local-redis. Вы можете сделать это, настроив spring.profiles.active
, Это также можно сделать во время выполнения, предоставив --spring.profiles.active=local,local-database,local-redis
свойство среды:
java -jar --spring.profiles.active=local,local-database,local-redis