Spring Boot配置跳过多个@Profile上的注册

时间:2016-02-07 10:24:05

标签: java spring spring-boot spring-profiles

我的Spring Boot应用程序具有不同的配置文件设置:devprodqcconsole等。

两个配置类的设置如下。 MyConfigurationA应为console以外的所有配置文件注册。 MyConfigurationB除了consoledev之外,我应该注册{。}}。

当我使用个人资料console运行应用程序时,MyConfigurationA未注册 - 这很好。但MyConfigurationB已注册 - 我不想要。我已按照以下方式设置@Profile注释,以便不为个人资料MyConfigurationBconsole注册dev

但是当我使用个人资料MyConfigurationB运行应用程序时console已注册。

@Profile({ "!" + Constants.PROFILE_CONSOLE ,  "!" + Constants.PROFILE_DEVELOPMENT })

文档(http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Profile.html)有一个包含一个配置文件但不包括另一个配置文件的示例。在我的例子中,我将两者都排除在@Profile({"!p1", "!p2"}):

之外
  

@Profile({“p1”,“!p2”}),如果出现注册   如果配置文件“p2”未激活,配置文件“p1”处于活动状态 OR

我的问题是:我们如何跳过两个配置文件的配置注册? @Profile({"!p1", "!p2"})正在执行OR操作。我们需要在这里进行AND操作。

代码:

@Configuration
@Profile({ "!" + Constants.PROFILE_CONSOLE  })
public class MyConfigurationA {
    static{
        System.out.println("MyConfigurationA registering...");
    }
}

@Configuration
@Profile({ "!" + Constants.PROFILE_CONSOLE ,  "!" + Constants.PROFILE_DEVELOPMENT }) // doesn't exclude both, its OR condition
public class MyConfigurationB {
    static{
        System.out.println("MyConfigurationB registering...");
    }
}

public final class Constants {
    public static final String PROFILE_DEVELOPMENT = "dev";
    public static final String PROFILE_CONSOLE = "console";
    ...
}

4 个答案:

答案 0 :(得分:19)

@Profile({"!console", "!dev"})表示(非控制台) OR (NOT dev)如果您使用配置文件“console”运行应用程序,则为true。 要解决此问题,您可以创建自定义Condition

public class NotConsoleAndDevCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        return !environment.acceptsProfiles("console", "dev");
    }
}

并通过@Conditional注释将条件应用于配置:

@Conditional(NotConsoleAndDevCondition.class)
public class MyConfigurationB {

答案 1 :(得分:8)

从Spring 5.1开始,您可以在@Profile批注中使用expressions。在@Profile documentation中了解更多信息。示例:

@Configuration
@Profile({ "!console & !dev" }) 
public class MyConfigurationB {
    static{
        System.out.println("MyConfigurationB registering...");
    }
}

答案 2 :(得分:1)

在较新版本的Spring中,已弃用了接受字符串的acceptsProfiles方法。

要执行与Cyril's question中相同的工作,您需要利用new method parameter。这种较新的格式还使您可以灵活地编写概要文件表达式,其功能比以前更强大,因此无需取消整个acceptsProfiles表达式本身。

public class NotConsoleAndDevCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        return environment.acceptsProfiles(Profiles.of("!console & !dev"));
    }
}

答案 3 :(得分:0)

另一种解决方案是,您可以不排除 2 个配置文件(控制台、开发人员),而只包含所有其他配置文件

@Profile({"qc", "prod"})