24

我有一个具有不同配置文件设置的 Spring Boot 应用程序:dev、、、prod等。qcconsole

两个配置类的设置如下。MyConfigurationA应该为所有配置文件注册,除了console. MyConfigurationB应该注册除了consoledev

当我使用 profile 运行应用程序时consoleMyConfigurationA没有注册 - 这很好。但是MyConfigurationB被注册了——我不想要。我已@Profile按如下方式设置注释,以不注册MyConfigurationBfor profile consoledev.

但是MyConfigurationB当我使用 profile 运行应用程序时,它正在注册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"}),如果配置文件 '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";
    ...
}
4

4 回答 4

41

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

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 {
于 2016-02-07T11:29:15.943 回答
16

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

@Configuration
@Profile({ "!console & !dev" }) 
public class MyConfigurationB {
    static{
        System.out.println("MyConfigurationB registering...");
    }
}
于 2020-01-07T15:31:23.523 回答
5

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

要完成与Cyril 问题中相同的工作,您需要利用新的方法参数。这种较新的格式还使您可以灵活地创作比以前更强大的配置文件表达式,从而消除否定整个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"));
    }
}
于 2019-02-26T20:37:09.410 回答
0

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

@Profile({"qc", "prod"})
于 2021-04-29T09:05:59.443 回答