Типичный подход — использовать папку для каждой среды, содержащую файлы с одинаковыми именами:
@Value("${name}")
private String name;
Затем параметризуйте @PropertySource, чтобы использовать переменную среды, например «env»:
@PropertySource
Теперь вам просто нужно убедиться, что в каждой среде существует определенная переменная среды операционной системы под названием «env», которая установлена правильно (т. е. dev, test, uat или prod). Вы не указали, как запускаете свое приложение (скрипт запуска сервера j2ee в Linux? Докер-контейнер Springboot?), Но установка переменной среды в каждой среде не должна быть проблемой.
Вместо того, чтобы загружать файлы из «${catalina.base}», вы можете загружать файлы из пути к классам, например:
src/main/resources/dev/application.properties
src/main/resources/test/application.properties
src/main/resources/uat/application.properties
src/main/resources/prod/application.properties
Если вы создаете с помощью maven, вы можете создать папки в разделе
src/main/resources
and they will be
скопировано в путь к классам:
// see https://stackoverflow.com/a/26387933/329496
@PropertySource("classpath:${env}/application.properties")
Это значительно упростило ситуацию. Дженкинсу вообще не нужно ничего делать, поскольку один и тот же артефакт сборки/выпуска можно запускать в любой среде. Обычно Дженкинсу приходится выполнять дополнительную работу по перенастройке приложения для работы в определенной среде. Скорее, вам следует стремиться к тому, чтобы одно задание выпуска Jenkins создавало артефакт, который можно было бы просто скопировать между средами.
У такого подхода есть один недостаток. Если вы хотите создать новую среду, вам необходимо добавить новый файл в систему управления версиями и создать новый артефакт выпуска. При использовании устаревших технологий настройка новых сред требует большой работы (например, ввод в эксплуатацию виртуальных машин и баз данных), поэтому этот «дополнительный шаг» по добавлению файла в код не кажется проблемой.
Благодаря более современным облачным технологиям, таким как Kubernetes, вы можете настроить среду за считанные секунды и «по требованию». В этом случае вы не хотите предварительно указывать свою среду в своей кодовой базе. Скорее вам следует следовать подходу 12factor.net и определять каждое свойство как переменную среды, а Spring просто использовать их напрямую. Если вы посмотрите на нынешнюю Springboot документация по умолчанию он использует переменные среды. Это означает, что если вы не определили
@PropertySource("file:${catalina.base}/conf/${env}/application.properties")
but you are using things like:
conf/dev/application.properties
conf/test/application.properties
conf/uat/application.properties
conf/prod/application.properties
они будут установлены из переменной среды то же имя, но с использованием всех заглавных букв. Тогда проблема переходит к тому, «как убедиться, что переменные среды правильно настроены в каждой среде». Технологии, которые позволяют легко развернуть среду за считанные секунды (kubernetes, cloudfoundry, swarm), также обычно упрощают управление переменными среды. С помощью kubernetes вы создаете «ConfigMap» (например, «my-app-properties») и имеете он монтируется как переменные среды где каждый ключ+значение определяет уникальную переменную среды для приложения. Каждая логическая среда может тогда представлять собой отдельное пространство имен Kubernetes (возможно, в общем кластере для разработки/тестирования, но в выделенном кластере для рабочей среды), которое имеет свой собственный объект конфигурации «my-app-properties», определяющий переменные среды для этой логической среды.
Вы можете поместить эти настройки под контроль версий, но не в репозиторий исходного кода приложения. Вместо этого вы можете использовать подход «инфраструктура как код», при котором все, что запускает приложение (например, все сценарии и yaml для настройки сред), находится в отдельном репозитории git. Затем вы можете настроить задание развертывания конфигурации, которое запускается веб-перехватчиком git в репозитории конфигурации. Это может привести к вытеснению новых переменных среды. Это позволяет вам осуществлять непрерывное развертывание изменений конфигурации, независимое от непрерывного развертывания кода приложения.
Если вы используете Kubernetes, то Helmfile — отличный выбор, поскольку он не будет обновлять в Kubernetes ничего, что не изменилось в git. Это означает, что можно безопасно повторно применять всю конфигурацию в репозитории git при каждом нажатии на защищенную главную ветку; helmfile дважды проверит, что уже развернуто, и обновит только те объекты конфигурации Kubernetes, которые необходимо обновить.