Как включать или отключать бины в Spring по профилям и какие аннотации использовать
Что проверяют
Понимаете ли вы, как Spring решает, регистрировать бин или нет, и чем профиль отличается от условной конфигурации. Следом обычно спрашивают, как активировать профиль в проде, что будет, если не активен ни один, и когда вместо @Profile лучше взять @ConditionalOnProperty.
Как отвечать
Основа:
@Profile: ставится на@Component, на класс@Configurationили на метод@Bean. Понимает отрицание и выражения:@Profile("!prod"),@Profile("dev & cloud"),@Profile("dev | test"). Внутри это обычный@ConditionalсProfileCondition;- активация: свойство
spring.profiles.active, переменная окруженияSPRING_PROFILES_ACTIVE, аргумент--spring.profiles.active=prod. Если не активен ни один, работает профильdefault, его меняют черезspring.profiles.default; - файлы:
application-dev.ymlподхватывается при активномdev. В многодокументном YAML начиная с Boot 2.4 документ привязывают черезspring.config.activate.on-profile, староеspring.profilesвнутри документа устарело. Для наборов есть группы:spring.profiles.group.prod=proddb,prodmq; - тесты:
@ActiveProfiles("test")на тестовом классе, в рабочем коде она ничего не делает.
Дальше покажите, что профили не единственный инструмент. Spring Boot даёт условия: @ConditionalOnProperty(name = "feature.cache.enabled", havingValue = "true") для фич под флагом, @ConditionalOnMissingBean для реализации по умолчанию. Профиль описывает окружение, условие описывает конкретную возможность, и смешивать их не стоит.
Где спотыкаются
Используют профили как фича-флаги: dev-with-kafka, prod-no-cache. Через полгода комбинаций больше, чем окружений, и никто не знает, какие бины реально поднимутся.
Коммитят spring.profiles.active=dev в общий application.properties. Если на сервере профиль не переопределили, прод стартует с dev-настройками.
Объявляют два @Bean одного типа под разными профилями и не думают о крайних случаях. Когда активны оба, внедрение падает с NoUniqueBeanDefinitionException, когда ни одного, с NoSuchBeanDefinitionException. Нужна реализация для default или взаимоисключающие условия вроде !prod.