提问者:小点点

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


我有一个具有不同配置文件设置的Spring Boot应用程序:devprodqc控制台等。

这两个配置类的设置如下。MyConfigurationA应该为除控制台之外的所有配置文件注册。MyConfigurationB应该为除控制台dev之外的所有配置文件注册。

当我使用profile控制台运行应用程序时,MyConfigurationA不会注册-这很好。但是MyConfigurationB会被注册-我不想要。我已经设置了@Profile注释,如下所示,以不注册profile控制台devMyConfigurationB

但是当我使用profile控制台运行应用程序时,MyConfigurationB正在注册。

@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"}):

@配置文件({"p1","! p2"}),如果配置文件'p1'处于活动状态或配置文件'p2'未处于活动状态,则将进行注册。

我的问题是:我们如何跳过两个配置文件配置的注册?@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";
    ...
}

共3个答案

匿名用户

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

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

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

@Conditional(NotConsoleAndDevCondition.class)
public class MyConfigurationB {

匿名用户

从Spring 5.1开始,您可以在@Profile注释中使用表达式。在@Profile留档中阅读更多信息。示例:

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

匿名用户

对于较新版本的Spring,接受字符串的方法已被弃用。

要像西里尔的问题一样做同样的工作,你需要利用新的方法参数。这种较新的格式还为您提供了比以前更强大的作者配置文件表达式的灵活性,从而消除了否定整个接受配置文件表达式本身的需要。

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