Можно ли сохранить файл конфигураций параметризованного приложения с конфигурациями, которые, скорее всего, изменятся в зависимости от обслуживания среды разработки, в другом файле, как указано ниже, в загрузочном приложении Spring с помощью инструмента, созданного maven?
Пример приложения.свойства
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/${MYSQL_DATABASE}?createDatabaseIfNotExist=true
spring.datasource.username=${MYSQL_USERNAME}
spring.datasource.password=${MYSQL_PASSWORD}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql=false
# Flyway Configuration
spring.flyway.enabled=true
spring.flyway.baseline-on-migrate=true
spring.flyway.user=${MYSQL_USERNAME}
spring.flyway.password=${MYSQL_PASSWORD}
spring.flyway.schemas=${MYSQL_DATABASE}
spring.flyway.url=jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/${MYSQL_DATABASE}?createDatabaseIfNotExist=true
spring.flyway.locations=classpath:db/migration
frontend.web.host=${FRONTEND_WEB_HOST_URL}
#links
login.URL = ${LOGIN_URL}/signin
prod.properties (новая конфигурация сохраняется на корневом уровне программы)
SPRING_PROFILES_ACTIVE=prod
MYSQL_HOST=178.18.10.16
MYSQL_PORT=3306
MYSQL_DATABASE=superdb
MYSQL_USERNAME=root
MYSQL_PASSWORD=123456
LOGIN_URL=178.18.10.16
FRONTEND_WEB_HOST_URL=http://localhost:3000
REACT_APP_HOST_URL=http://localhost:8080
REACT_APP_API=/api
Если этот процесс возможен в Spring Boot, как это приложение должно выполняться через командную строку и Eclipse IDE?
При попытке выполнить его через консоль с помощью приведенной ниже команды я получаю эту ошибку.
Используемая команда mvn Spring-boot:run -Dspring-boot.run.profiles=prod
Указана ошибка
java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-3.0.5.jar:3.0.5]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-6.0.7.jar:6.0.7]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$TrackedConditionEvaluator.shouldSkip(ConfigurationClassBeanDefinitionReader.java:466) ~[spring-context-6.0.7.jar:6.0.7]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$TrackedConditionEvaluator.shouldSkip(ConfigurationClassBeanDefinitionReader.java:455) ~[spring-context-6.0.7.jar:6.0.7]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:131) ~[spring-context-6.0.7.jar:6.0.7]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[spring-context-6.0.7.jar:6.0.7]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:410) ~[spring-context-6.0.7.jar:6.0.7]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:283) ~[spring-context-6.0.7.jar:6.0.7]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:344) ~[spring-context-6.0.7.jar:6.0.7]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:115) ~[spring-context-6.0.7.jar:6.0.7]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:747) ~[spring-context-6.0.7.jar:6.0.7]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:565) ~[spring-context-6.0.7.jar:6.0.7]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.0.5.jar:3.0.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[spring-boot-3.0.5.jar:3.0.5]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-3.0.5.jar:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[spring-boot-3.0.5.jar:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1304) ~[spring-boot-3.0.5.jar:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1293) ~[spring-boot-3.0.5.jar:3.0.5]
at com.antarctica21.backend.Antarctica21BackendApplication.main(Antarctica21BackendApplication.java:16) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-3.0.5.jar:3.0.5]
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'MYSQL_HOST' in value "jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/${MYSQL_DATABASE}?createDatabaseIfNotExist=true"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:180) ~[spring-core-6.0.7.jar:6.0.7]
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) ~[spring-core-6.0.7.jar:6.0.7]
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:239) ~[spring-core-6.0.7.jar:6.0.7]
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210) ~[spring-core-6.0.7.jar:6.0.7]
at org.springframework.core.env.AbstractPropertyResolver.resolveNestedPlaceholders(AbstractPropertyResolver.java:230) ~[spring-core-6.0.7.jar:6.0.7]
at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.getProperty(ConfigurationPropertySourcesPropertyResolver.java:79) ~[spring-boot-3.0.5.jar:3.0.5]
at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.getProperty(ConfigurationPropertySourcesPropertyResolver.java:60) ~[spring-boot-3.0.5.jar:3.0.5]
at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:552) ~[spring-core-6.0.7.jar:6.0.7]
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition$Spec.collectProperties(OnPropertyCondition.java:121) ~[spring-boot-autoconfigure-3.0.5.jar:3.0.5]
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition.determineOutcome(OnPropertyCondition.java:71) ~[spring-boot-autoconfigure-3.0.5.jar:3.0.5]
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition.getMatchOutcome(OnPropertyCondition.java:58) ~[spring-boot-autoconfigure-3.0.5.jar:3.0.5]
at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberOutcomes.getConditionOutcome(AbstractNestedCondition.java:195) ~[spring-boot-autoconfigure-3.0.5.jar:3.0.5]
at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberOutcomes.<init>(AbstractNestedCondition.java:189) ~[spring-boot-autoconfigure-3.0.5.jar:3.0.5]
at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberConditions.lambda$getMatchOutcomes$0(AbstractNestedCondition.java:169) ~[spring-boot-autoconfigure-3.0.5.jar:3.0.5]
at java.base/java.util.Map.forEach(Map.java:713) ~[na:na]
at java.base/java.util.Collections$UnmodifiableMap.forEach(Collections.java:1553) ~[na:na]
at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberConditions.getMatchOutcomes(AbstractNestedCondition.java:169) ~[spring-boot-autoconfigure-3.0.5.jar:3.0.5]
at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberMatchOutcomes.<init>(AbstractNestedCondition.java:78) ~[spring-boot-autoconfigure-3.0.5.jar:3.0.5]
at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition.getMatchOutcome(AbstractNestedCondition.java:63) ~[spring-boot-autoconfigure-3.0.5.jar:3.0.5]
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-3.0.5.jar:3.0.5]
Что именно вы подразумеваете под «динамическим изменением»? Если данные в конфигурации изменяются во время работы программы, она должна немедленно реагировать? Или конфигурация может меняться при запуске программного обеспечения, но вы не хотите изменять для этого файл JAR/WAR/EAR/любой другой файл?
Я хочу отметить, что большинство bean-компонентов (и определенно bean-компонентов источника данных) имеют одноэлементную область действия и будут созданы при запуске, поэтому изменение заполнителя/свойств не окажет никакого влияния на эти bean-компоненты, поскольку эти bean-компоненты уже давно созданы. Уточните, пожалуйста, что именно вам нужно сделать при изменении свойств
Переменные среды и файлы свойств — это разные вещи. Исправьте заголовок.
Извиняюсь за путаницу в моем первоначальном вопросе. Я пересмотрел его для большей ясности. Я пытаюсь добиться использования внешних файлов конфигурации для хранения настроек, специфичных для среды, таких как учетные данные базы данных, которые могут меняться в зависимости от среды развертывания. В частности, я хочу, чтобы значения, определенные в файле prod.properties, использовались в файле application.properties в приложении Spring Boot. Как это можно правильно реализовать?
Вы читали документацию по внешней конфигурации Spring Boot ?
Чтобы выполнить приложение Spring Boot с конфигурациями, специфичными для среды, например, определенными в prod.properties, вам необходимо убедиться, что правильный профиль (в данном случае prod) активен и файл конфигурации правильно загружен.
1. Командная строка
Вы можете использовать следующую команду для запуска приложения Spring Boot из командной строки:
SPRING_PROFILES_ACTIVE=prod MYSQL_HOST=178.18.10.16 MYSQL_PORT=3306 MYSQL_DATABASE=superdb MYSQL_USERNAME=root MYSQL_PASSWORD=123456 LOGIN_URL=178.18.10.16 mvn spring-boot:run
Альтернативно вы можете загрузить переменные среды из файла prod.properties, предоставив его перед запуском приложения Spring Boot:
source backend-service/prod.properties
mvn spring-boot:run
Или вы можете передать файл prod.properties в качестве переменных среды при запуске приложения:
env $(cat backend-service/prod.properties | xargs) mvn spring-boot:run -Dspring-boot.run.profiles=prod
2. Затмение IDE
В Eclipse вы можете выполнить следующие шаги:
Открытые конфигурации запуска: Щелкните правой кнопкой мыши свой проект в обозревателе проектов и выберите «Запуск от имени» > «Выполнить конфигурации».
Установите переменные среды:
На вкладке «Среда» вручную добавьте каждую переменную среды (например, SPRING_PROFILES_ACTIVE, MYSQL_HOST, MYSQL_PORT и т. д.), нажав «Создать...» и введя имя и значение переменной.
Установить активный профиль: На вкладке «Аргументы» в разделе «Аргументы виртуальной машины» добавьте: -Dspring.profiles.active=prod.
Запустите приложение Нажмите «Применить», а затем «Выполнить».
3. IntelliJ ИДЕЯ
В IntelliJ IDEA выполните следующие действия:
Редактировать конфигурации: Перейдите в «Выполнить» > «Редактировать конфигурации»....
Установите переменные среды: В разделе «Конфигурация» в разделе «Переменные среды» добавьте каждую переменную среды (например, SPRING_PROFILES_ACTIVE, MYSQL_HOST и т. д.). Вы можете ввести их в текстовое поле в формате КЛЮЧ=ЗНАЧЕНИЕ, разделенные точкой с запятой, или нажать кнопку ..., чтобы ввести их по отдельности.
Установить активный профиль: В поле «Параметры виртуальной машины» добавьте: -Dspring.profiles.active=prod.
Запустите приложение
Попробуйте
spring.config.import
указать файл