Конфигурация и сборка Spring-приложения

Собранный artifact должен быть одинаковым для окружений. Меняются внешние properties, secrets и infrastructure endpoints, а не исходники и не отдельная “production-сборка”.

Конфигурация

Spring Boot собирает properties из нескольких источников с определённым приоритетом: packaged config, profile-specific config, внешние файлы, environment variables, system/command-line properties. При конфликте побеждает источник с более высоким приоритетом.

app:
  batch-size: 100
  request-timeout: 2s
 
spring:
  datasource:
    url: ${DB_URL}
    username: ${DB_USER}
    password: ${DB_PASSWORD}

Environment variable подставляет secret в runtime. В repository храню только имена и безопасные defaults, не реальные credentials.

Типизированные properties

@ConfigurationProperties(prefix = "app")
@Validated
public record AppProperties(
        @Min(1) int batchSize,
        @NotNull Duration requestTimeout
) {}

Типизированная конфигурация даёт binding, validation и единое место контракта. Строковый environment.getProperty оставляю для действительно динамического lookup, а не основной модели настроек.

Profiles

Profile переключает согласованный набор beans/properties, но не должен разрастаться в условное программирование на каждое окружение.

java -jar app.jar --spring.profiles.active=demo

Имена и endpoints конкретного окружения лучше передавать значениями. Если prod profile меняет бизнес-логику, tests легко проверят не тот вариант.

Сборка

./mvnw clean verify
./mvnw package
java -jar target/app.jar

Spring Boot plugin может упаковать executable JAR с dependencies и launcher. Обычный Maven JAR и bootable JAR имеют разную внутреннюю layout; это проверяю через jar tf.

Диагностика

При ошибке binding читаю полный property path, expected type и источник значения. Для production Actuator/config endpoints могут раскрывать secrets, поэтому доступ и sanitization обязательны.

Для Kafka я вынес bootstrap servers во внешнюю конфигурацию, чтобы один artifact работал в разных окружениях. См. Кейс конфигурация Kafka в разных окружениях.

Типичные сбои

  • Закоммитить application-prod.yml с паролем.
  • Переопределить property command-line аргументом и забыть об этом.
  • Использовать profile для каждого host.
  • Собрать новый JAR для изменения endpoint.
  • Не валидировать обязательное значение и упасть при первом request.
  • Запустить Maven и IDE на разных JDK.

Вопросы для собеседования

Зачем externalized configuration? Один проверенный artifact запускается в разных окружениях без пересборки.

Чем @ConfigurationProperties лучше набора @Value? Группирует контракт, поддерживает type-safe binding и validation.

Где хранить secrets? Во внешнем secret store/environment с контролем доступа, не в repository и artifact.

Зачем profiles? Включать согласованный вариант beans/config, когда обычных значений недостаточно.

Что делает mvn verify? Выполняет lifecycle до проверки package, включая связанные tests/checks проекта.

См. Spring Boot, Основы иcпользования Maven, Артефакт.