我有一个具有不同配置文件设置的Spring Boot应用程序:dev
、prod
、qc
、控制台
等。
这两个配置类的设置如下。MyConfigurationA
应该为除控制台
之外的所有配置文件注册。MyConfigurationB
应该为除控制台
和dev
之外的所有配置文件注册。
当我使用profile控制台
运行应用程序时,MyConfigurationA
不会注册-这很好。但是MyConfigurationB
会被注册-我不想要。我已经设置了@Profile
注释,如下所示,以不注册profile控制台
和dev
的MyConfigurationB
。
但是当我使用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";
...
}
@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"));
}
}