Как описать разные свойства для каждого профиля в Spring
Что проверяют
Знаете ли вы, как Spring Boot собирает конфигурацию из нескольких источников и что побеждает при конфликте. Следом обычно спрашивают, где хранить пароли от продовой базы и как включить профиль в контейнере.
Как отвечать
Основной способ это файлы рядом с общим:
application.yml: настройки для всех окружений;application-dev.yml,application-prod.yml: только то, что отличается. Профильный файл не заменяет общий, а накладывается сверху и переопределяет совпавшие ключи;- один YAML на всё: документы разделяются
---, у профильного указываетсяspring.config.activate.on-profile: prod. Старый ключspring.profilesвнутри документа устарел с Spring Boot 2.4; - группы:
spring.profiles.group.prod=proddb,prodmqвключает несколько профилей одним именем.
Профиль включается через spring.profiles.active: аргументом --spring.profiles.active=prod, системным свойством через -D или переменной SPRING_PROFILES_ACTIVE, что удобнее всего в контейнере. Если активно несколько профилей, при конфликте выигрывает последний в списке. Когда ни один не задан, работает профиль default.
Бины по профилю отбирает @Profile("prod"), допустимы выражения вроде @Profile("!prod"). В тестах профиль включает @ActiveProfiles("test"). Сами свойства удобнее читать через @ConfigurationProperties с валидацией, а не россыпью @Value.
Секреты в профильные файлы не кладут: пароли приходят из переменных окружения, Kubernetes Secret или Vault. Благодаря relaxed binding переменная SPRING_DATASOURCE_PASSWORD сама попадёт в spring.datasource.password.
Где спотыкаются
Пытаются включить профиль изнутри профильного файла, прописав spring.profiles.active в application-dev.yml. Начиная с Spring Boot 2.4 это ошибка при старте.
Считают, что application-prod.yml полностью заменяет общий файл, и копируют туда все настройки. Потом общий ключ меняют в одном месте, а прод живёт по старой копии.
Коммитят продовые пароли в application-prod.yml. Даже в приватном репозитории это утечка, которую потом приходится вычищать из истории git.