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

gti*_*333 15 java spring spring-profiles spring-boot

我曾与不同的配置文件设置一个春天启动应用程序:dev,prod,qc,console等.

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

当我使用配置文件运行应用程序时console,MyConfigurationA没有注册 - 这很好.但MyConfigurationB得到注册 - 我不想要.我已@Profile按如下方式设置注释,以便不注册MyConfigurationBfor profile consoledev.

但是MyConfigurationB当我使用配置文件运行应用程序时,它正在注册console.

@Profile({ "!" + Constants.PROFILE_CONSOLE ,  "!" + Constants.PROFILE_DEVELOPMENT })
Run Code Online (Sandbox Code Playgroud)

的文件(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";
    ...
}
Run Code Online (Sandbox Code Playgroud)

Cyr*_*ril 21

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

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

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

@Conditional(NotConsoleAndDevCondition.class)
public class MyConfigurationB {
Run Code Online (Sandbox Code Playgroud)

  • 您可以将配置文件表达式(以配置文件作为操作数的逻辑表达式)与 @Profile 注释一起使用,而不是创建自定义条件。例如:@Profile({"!p1 & !p2"}) 参考:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Profile.html (3认同)

xyz*_*xyz 11

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

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


Mak*_*oto 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"));
    }
}
Run Code Online (Sandbox Code Playgroud)