Как использовать внешние файлы конфигурации для обеспечения специфичных для среды конфигураций в приложении Spring Boot?

Можно ли сохранить файл конфигураций параметризованного приложения с конфигурациями, которые, скорее всего, изменятся в зависимости от обслуживания среды разработки, в другом файле, как указано ниже, в загрузочном приложении 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]

Попробуйте spring.config.import указать файл

retmas 27.08.2024 13:31

Что именно вы подразумеваете под «динамическим изменением»? Если данные в конфигурации изменяются во время работы программы, она должна немедленно реагировать? Или конфигурация может меняться при запуске программного обеспечения, но вы не хотите изменять для этого файл JAR/WAR/EAR/любой другой файл?

cyberbrain 27.08.2024 13:31

Я хочу отметить, что большинство bean-компонентов (и определенно bean-компонентов источника данных) имеют одноэлементную область действия и будут созданы при запуске, поэтому изменение заполнителя/свойств не окажет никакого влияния на эти bean-компоненты, поскольку эти bean-компоненты уже давно созданы. Уточните, пожалуйста, что именно вам нужно сделать при изменении свойств

J Asgarov 27.08.2024 13:51

Переменные среды и файлы свойств — это разные вещи. Исправьте заголовок.

aled 27.08.2024 14:20

Извиняюсь за путаницу в моем первоначальном вопросе. Я пересмотрел его для большей ясности. Я пытаюсь добиться использования внешних файлов конфигурации для хранения настроек, специфичных для среды, таких как учетные данные базы данных, которые могут меняться в зависимости от среды развертывания. В частности, я хочу, чтобы значения, определенные в файле prod.properties, использовались в файле application.properties в приложении Spring Boot. Как это можно правильно реализовать?

Gehan 27.08.2024 16:08

Вы читали документацию по внешней конфигурации Spring Boot ?

Chin Huang 27.08.2024 17:36
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы выполнить приложение 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.

Запустите приложение

Другие вопросы по теме