Spring Profiles: малоизвестный нюанс, который может удивить
Все знают классический вариант:
@Profile("prod")
@Bean
public PaymentClient paymentClient() {
return new PaymentClient();
}
Если активен prod — Bean создаётся.
Если нет — Spring его не создаёт.
Но у Profiles есть несколько интересных возможностей.
1. Профили умеют выражения
Можно написать:
@Profile("prod & !test")
Bean будет создан, только если:
prod = активен
test = НЕ активен
Можно и так:
@Profile("prod | stage")
То есть Bean нужен либо для prod, либо для stage.
2. Профиль можно включить вместе с другим
Например, у нас есть:
application.yml
application-prod.yml
application-monitoring.yml
И в конфигурации:
spring:
profiles:
include:
- monitoring
Если активировать: prod
Spring дополнительно активирует: monitoring
Получается:
prod
↓
monitoring
И это удобно, например, когда набор настроек должен автоматически подключаться к определённому окружению.
3. А вот здесь легко ошибиться
Не стоит воспринимать Profiles как полноценную систему управления конфигурацией.
Например:
@Profile("prod")
@Bean
public PaymentService paymentService() {
return new PaymentService();
}
Это не означает, что PaymentService будет существовать только в production.
Это означает только:
данный Bean будет создан, когда условие Profile выполнено.
То есть @Profile — это условие создания Bean, а не просто переключатель YAML-файлов.
И ещё один момент, который полезно помнить:
@Profile("prod")
и:
spring:
profiles:
active: prod
— это разные вещи.
Первое говорит:
при каком профиле создавать Bean.
Второе:
какой профиль сейчас активировать.
Условно:
spring.profiles.active
↓
какие профили активны?
↓
@Profile(...)
↓
какие Bean создавать?
Поэтому если @Profile("prod") внезапно «не работает», первым делом стоит проверить не сам Bean, а какие профили реально активны.
А Profiles — это не просто:
dev / test / prod.
Это ещё один механизм, с помощью которого Spring условно формирует ApplicationContext.