Как получить текущий активный / заданный по умолчанию профиль среды программным способом в Spring?

155

Мне нужно кодировать другую логику, основанную на разных текущих профилях среды Как вы можете получить текущие активные и стандартные профили из Spring?

Бобо
источник
3
@aweigold: получить текущий активный / стандартный профиль среды программно весной 3.1. какие еще детали вам нужны?
Бобо

Ответы:

76

Расширение приятного простого ответа User1648825 (я не могу комментировать, и моя правка была отклонена):

@Value("${spring.profiles.active}")
private String activeProfile;

Это может вызвать исключение IllegalArgumentException, если профили не заданы (я получаю нулевое значение). Это может быть хорошей вещью, если вам нужно ее установить; если нет, используйте синтаксис «по умолчанию» для @Value, то есть:

@Value("${spring.profiles.active:Unknown}")
private String activeProfile;

... activeProfile теперь содержит «Unknown», если не удалось разрешить spring.profiles.active

MartinMlima
источник
Имена профилей разделены запятой. Оформить заказ baeldung.com/spring-profiles#2-using-springactiveprofile
Джейсон
56

Вот более полный пример.

Autowire Environment

Сначала вы захотите автоматически подключить компонент среды.

@Autowired
private Environment environment;

Проверьте, существуют ли профили в активных профилях

Затем вы можете использовать, getActiveProfiles()чтобы узнать, существует ли профиль в списке активных профилей. Вот пример, который берет String[]from getActiveProfiles(), получает поток из этого массива, а затем использует matchers для проверки нескольких профилей (без учета регистра), который возвращает логическое значение, если они существуют.

//Check if Active profiles contains "local" or "test"
if(Arrays.stream(environment.getActiveProfiles()).anyMatch(
   env -> (env.equalsIgnoreCase("test") 
   || env.equalsIgnoreCase("local")) )) 
{
   doSomethingForLocalOrTest();
}
//Check if Active profiles contains "prod"
else if(Arrays.stream(environment.getActiveProfiles()).anyMatch(
   env -> (env.equalsIgnoreCase("prod")) )) 
{
   doSomethingForProd();
}

Вы также можете достичь аналогичной функциональности, используя аннотации @Profile("local")Профили позволяют выборочную настройку на основе переданного параметра или параметра среды. Вот больше информации об этой технике: Spring Profiles

anataliocs
источник
2
@Profile кажется лучшим решением.
Пол Уолдо
Я ослеплен отдельными строчками для каждой фигурной скобки. Не стандарты Java кодирования.
user1567291
26
@Value("${spring.profiles.active}")
private String activeProfile;

Это работает, и вам не нужно реализовывать EnvironmentAware. Но я не знаю недостатков этого подхода.

user1648825
источник
3
Эта строка дает эту ошибку:Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.profiles.active' in value "${spring.profiles.active}"
Zygimantus
Отлично работает для меня Использование Spring Boot 1.5.15.
рüффп
Я думаю, что если профиль определен, значение будет проанализировано, в противном случае возникает исключение. Не подходит для всех ситуаций.
WesternGun
1
Активный профиль также может быть массивом, обратите на это внимание, пожалуйста. При таком способе вы можете получить неожиданную ошибку при добавлении дополнительных профилей.
Алексей Ефимов
Недостаток этого подхода заключается в том, что он не получит все профили, которые Spring может учитывать при оценке @Profile. Приложения также могут использовать это spring.profiles.include свойство и могут программно устанавливать профили во время инициализации с помощью ConfigurableEnvironment. Environment.getActiveProfiles()получит полный список профилей, установленных с помощью любого из этих механизмов.
Скотт Фредерик
14

Если вы не используете автопроводку, просто внедрите EnvironmentAware

Арно Энгелен
источник
0

Кажется, есть некоторый спрос на статический доступ к этому.

Как я могу получить такую ​​вещь в статических методах в неуправляемых классах? - Эфир

Это хак, но вы можете написать свой собственный класс, чтобы разоблачить его. Вы должны быть осторожны, чтобы убедиться, что ничто не будет вызываться SpringContext.getEnvironment()до того, как будут созданы все bean-компоненты, поскольку нет гарантии, когда будет создан этот компонент.

@Component
public class SpringContext
{
    private static Environment environment;

    public SpringContext(Environment environment) {
        SpringContext.environment = environment;
    }

    public static Environment getEnvironment() {
        if (environment == null) {
            throw new RuntimeException("Environment has not been set yet");
        }
        return environment;
    }
}
Майкл
источник