YAML 对象上的@ConditionalOnProperty
@ConditionalOnProperty on YAML objects
我有一个如下所示的 YAML:
client:
auth:
foo:
something: 123
whatever: 321
bar:
idk: 999
anything: bleh
我正在尝试创建 bean,无论它们是否在该 YAML 上指定,例如:
@Bean
@ConditionalOnProperty(prefix = "client.auth", name = "foo")
public Foo foo() {
return new Foo();
}
@Bean
@ConditionalOnProperty(prefix = "client.auth", name = "bar")
public Bar bar() {
return new Bar();
}
这样的 YAML 应该只创建 Bar
bean(没有指定 client.auth.foo
):
client:
auth:
bar:
idk: 999
anything: bleh
但是,这不起作用(未创建 bean)。我还尝试了以下方法(为简洁起见省略了 foo - bar):
@Bean
@ConditionalOnProperty(prefix = "client.auth", value = "foo")
public Foo foo() {
return new Foo();
}
@Bean
@ConditionalOnProperty(prefix = "client", name = "auth", havingValue = "foo")
public Foo foo() {
return new Foo();
}
是否有可能实现我正在寻找的东西?怎么样?
方法 #1:
ConditionalOnProperty 处理完整的 属性 名称。对于您的用例,如果您可以添加一个额外的布尔参数,如 client.auth.foo.enabled,那么可能会起作用。如下图所示:
@Bean
@ConditionalOnProperty(value = "client.auth.foo.enabled", havingValue = "true")
public Foo foo() {
return new Foo();
}
对应的yaml文件
client:
auth:
foo:
enabled: true
something: 123
whatever: 321
方法 #2:
您可以实现自己的条件来检查 属性 前缀是否存在。
@Bean
@Conditional(MyCondition.class)
public Foo foo() {
return new Foo();
}
static class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
final String prefix = "client.auth.foo";
if (context.getEnvironment() instanceof ConfigurableEnvironment env) {
for (PropertySource<?> propertySource : env.getPropertySources()) {
if (propertySource instanceof EnumerablePropertySource enumerablePropertySource) {
for (String key : enumerablePropertySource.getPropertyNames()) {
if (key.startsWith(prefix)) {
return true;
}
}
}
}
}
return false;
}
}
基于 针对您的用例进行了修改
我有一个如下所示的 YAML:
client:
auth:
foo:
something: 123
whatever: 321
bar:
idk: 999
anything: bleh
我正在尝试创建 bean,无论它们是否在该 YAML 上指定,例如:
@Bean
@ConditionalOnProperty(prefix = "client.auth", name = "foo")
public Foo foo() {
return new Foo();
}
@Bean
@ConditionalOnProperty(prefix = "client.auth", name = "bar")
public Bar bar() {
return new Bar();
}
这样的 YAML 应该只创建 Bar
bean(没有指定 client.auth.foo
):
client:
auth:
bar:
idk: 999
anything: bleh
但是,这不起作用(未创建 bean)。我还尝试了以下方法(为简洁起见省略了 foo - bar):
@Bean
@ConditionalOnProperty(prefix = "client.auth", value = "foo")
public Foo foo() {
return new Foo();
}
@Bean
@ConditionalOnProperty(prefix = "client", name = "auth", havingValue = "foo")
public Foo foo() {
return new Foo();
}
是否有可能实现我正在寻找的东西?怎么样?
方法 #1:
ConditionalOnProperty 处理完整的 属性 名称。对于您的用例,如果您可以添加一个额外的布尔参数,如 client.auth.foo.enabled,那么可能会起作用。如下图所示:
@Bean
@ConditionalOnProperty(value = "client.auth.foo.enabled", havingValue = "true")
public Foo foo() {
return new Foo();
}
对应的yaml文件
client:
auth:
foo:
enabled: true
something: 123
whatever: 321
方法 #2:
您可以实现自己的条件来检查 属性 前缀是否存在。
@Bean
@Conditional(MyCondition.class)
public Foo foo() {
return new Foo();
}
static class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
final String prefix = "client.auth.foo";
if (context.getEnvironment() instanceof ConfigurableEnvironment env) {
for (PropertySource<?> propertySource : env.getPropertySources()) {
if (propertySource instanceof EnumerablePropertySource enumerablePropertySource) {
for (String key : enumerablePropertySource.getPropertyNames()) {
if (key.startsWith(prefix)) {
return true;
}
}
}
}
}
return false;
}
}
基于