将@Profile注释与属性占位符值一起使用

时间:2014-09-01 08:59:55

标签: spring spring-boot

当我们为spring中的任何组件定义profile时,我们将其声明为 @Profile(value="Prod")。但我想从属性文件中提供该值。 可能吗?如果是,怎么样?

3 个答案:

答案 0 :(得分:5)

您似乎试图滥用@Profile注释。使用配置文件启用功能。不是说Bean在特定环境中是活跃的。

实现更接近我认为您正在寻找的东西的方法是使用特定于您的环境的属性文件,这些属性文件定义应在其中激活的配置文件。这样,您就可以使用arg启动应用程序,例如:

--spring.profiles.active=prd
然后,

Spring Boot将尝试加载application-prd.properties,您可以在其中激活特定于环境的配置文件:

spring.profiles.active=sqlserver,activedirectory,exchangeemail

这样,只有在需要提供功能时才会激活您的bean。

答案 1 :(得分:4)

通过Spring的源代码,我得出的结论是,你所要求的是不可能的。为了明确这一点,我们无法在${property}内评估@Profile

具体来看ProfileCondition,它会检查个人资料是否有效。

class ProfileCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        if (context.getEnvironment() != null) {
            MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
            if (attrs != null) {
                for (Object value : attrs.get("value")) {
                    if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
                        return true;
                    }
                }
                return false;
            }
        }
        return true;
    }

}

肉是context.getEnvironment().acceptsProfiles(((String[]) value))

现在,如果您检查AbstractEnvironment所在的acceptsProfiles的来源,您会发现控件已到达

protected boolean isProfileActive(String profile) {
    validateProfile(profile);
    return doGetActiveProfiles().contains(profile) ||
            (doGetActiveProfiles().isEmpty() && doGetDefaultProfiles().contains(profile));
}

不会尝试计算表达式,但会逐字逐句地获取字符串(另请注意,isProfileActive之前的任何地方都是被评估的字符串表达式)

您可以找到我上面提到的代码herehere


另外请注意,我不确定为什么你需要一个动态的个人资料名称。

答案 2 :(得分:1)

另一种方法是在创建ApplicationContext时:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ConfigClass.class);
String profile = aplicationContext.getEnvironemnt().getRequiredProperty("profile");
applicationContext.getEnvironment().setActiveProfiles(profile);