在Spring中,如何以编程方式获取当前活动/默认环境配置文件?

254

我需要根据不同的当前环境配置编写不同的逻辑。

你如何从Spring中获取当前活动和默认配置文件?


4
在Spring 3.1中以编程方式获取当前活动/默认环境配置文件。还需要哪些详细信息? - Bobo
10个回答

337

21
我该如何在非Spring管理的类中使用静态方法来获取这样的东西? - Aetherus
1
我会尝试将profile-name作为方法参数添加,并从调用类中传递它。 - boutta
看起来Spring 5.1已经弃用了acceptsProfiles(String... profiles)方法,并用acceptsProfiles(Profiles profiles)方法替换了它。 - M. Justin

141

扩展User1648825简短明了的回答:

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

如果没有设置配置文件(我得到一个空值),则可能会抛出IllegalArgumentException异常。 如果需要设置它,则这可能是一件好事; 如果不需要,请使用@Value的“default”语法,即:

如果没有配置文件,则@Value使用默认值。例如:@Value($ {'my.property:default'})

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

如果无法解析spring.profiles.active,则activeProfile现在包含“Unknown”


2
配置文件名用逗号隔开。请访问 https://www.baeldung.com/spring-profiles#2-using-springactiveprofile。 - Jason
1
在SpringBootTest中注入get时无法正常工作。注入环境可以正常工作。 - Wood
请参阅有关@SpringBootTest@ActiveProfiles的讨论,以及从Spring Boot 2.3开始为什么/如何进行了更改此处 - hello_earth
请查看此处关于@SpringBootTest@ActiveProfiles的讨论,以及它从Spring Boot 2.3开始如何被修改 链接 - hello_earth

75

这里有一个更完整的例子。

自动装配环境

首先,您需要自动装配环境bean。

@Autowired
private Environment environment;

检查活动配置文件中是否存在配置文件

接下来,您可以使用getActiveProfiles()来查找该配置文件是否存在于活动配置文件列表中。以下是一个示例,它获取来自getActiveProfiles()String[],从该数组获取一个流,然后使用匹配器检查多个配置文件(不区分大小写),如果它们存在,则返回布尔值。

//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


3
@Profile 似乎是最好的解决方案。 - Paul Waldo

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

这个方法是可行的,而且不需要实现EnvironmentAware。但我不知道这种方法的缺点。


8
这行代码报错:Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.profiles.active' in value "${spring.profiles.active}" - zygimantus
我认为如果定义了配置文件,则会解析值,否则会引发异常。这并不适用于所有情况。 - WesternGun
3
活动配置文件也可以是一个数组,请注意。使用这种方式可能会在添加其他配置文件时出现意外错误。 - Oleksandr Yefymov
2
这种方法的缺点是它不能获取Spring在评估@Profile时可能考虑的所有配置文件。应用程序还可以使用spring.profiles.include属性,并且可以在初始化期间使用ConfigurableEnvironment编程设置配置文件。Environment.getActiveProfiles()将获取使用任何这些机制设置的完整配置文件列表。 - Scott Frederick
我得到了 null。 - Girish
显示剩余2条评论

21

如前所述,您可以使用自动装配来注入Environment

@Autowired
private Environment environment;

只有您可以更轻松地检查所需环境:

if (environment.acceptsProfiles(Profiles.of("test"))) {
    doStuffForTestEnv();
} else {
    doStuffForOtherProfiles();
}

17

如果您没有使用自动装配,请简单实现 EnvironmentAware 接口


2
仅在实现接口的类由Spring管理时才有效。 - Manuel

10

似乎有一些需求可以静态访问此内容。

如何在非 Spring 管理的类中的静态方法中获得这种功能?- Aetherus

这是一个 hack,但您可以编写自己的类来公开它。您必须小心确保在所有 bean 创建之前没有任何东西会调用 SpringContext.getEnvironment(),因为无法保证何时将实例化此组件。

@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;
    }
}

谢谢!那很有帮助,因为我需要在静态方法上使用它! - renanleandrof

6

如果您既不希望使用@Autowire,也不希望注入@Value,您可以简单地执行以下操作(包括回退):

System.getProperty("spring.profiles.active", "unknown");

这将返回任何活动的配置文件(或回退到“未知”)。

这对我不起作用。 - Peter S.
对我也没用 - sueszli
我猜想在这种情况下,必须将spring.profiles.active设置为VM参数才能使其正常工作。 - Wortig

0
使用Spring 5.3.28,事情可以变得更简单:
  1. 自动装配Environment
  2. 使用boolean matchesProfiles(String... profileExpressions)
例如:
@Autowired
private Environment environment;

...

if (env.matchesProfiles("online")) {
  ...
}

0
在Spring Boot中使用服务
@Service
class ProfileService(
    val environment: Environment
) {
    fun get(): Profile? {
        return Profile[environment.activeProfiles.firstOrNull()]
    }

    fun isTest(): Boolean {
        return get() != Profile.PRD
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接