我的Spring Boot应用程序具有不同的配置文件设置:dev
,prod
,qc
,console
等。
两个配置类的设置如下。 MyConfigurationA
应为console
以外的所有配置文件注册。 MyConfigurationB
除了console
和dev
之外,我应该注册{。}}。
当我使用个人资料console
运行应用程序时,MyConfigurationA
未注册 - 这很好。但MyConfigurationB
已注册 - 我不想要。我已按照以下方式设置@Profile
注释,以便不为个人资料MyConfigurationB
和console
注册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";
...
}
答案 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"})