I have an YAML that looks like this:
client:
auth:
foo:
something: 123
whatever: 321
bar:
idk: 999
anything: bleh
I'm trying to create beans whether they're specified on that YAML, example:
@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();
}
Such YAML should create only the Bar bean (no client.auth.foo specified):
client:
auth:
bar:
idk: 999
anything: bleh
However, this does not work (beans aren't created). I've also tried the following (foo's - bar's omitted for brevity):
@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();
}
Is it possible to achieve what I'm looking for? How?
CodePudding user response:
Approach #1:
ConditionalOnProperty work on the complete property name. For your usecase, something that could work is if you can add an additional boolean parameter like client.auth.foo.enabled. Like shown below:
@Bean
@ConditionalOnProperty(value = "client.auth.foo.enabled", havingValue = "true")
public Foo foo() {
return new Foo();
}
Corresponding yaml file
client:
auth:
foo:
enabled: true
something: 123
whatever: 321
Approach #2:
You can implement your own Condition to check whether the property prefix exist.
@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;
}
}
Based on https://stackoverflow.com/a/47873601 modified for your usecase
