Is there any way to use @ConditionalOnProperty twice for the same bean?
I have two properties, that are mapped to "A" or "B" individually.
Spring configuration:
@Bean
@ConditionalOnProperty(prefix = "app.config.inside", name = "prop", havingValue = "a")
@ConditionalOnProperty(prefix = "app.config.outside", name = "prop", havingValue = "a") //??
public SomeBean beanForPropA() {
return new SomeBean1();
}
@Bean
@ConditionalOnProperty(prefix = "app.config.inside", name = "prop", havingValue = "b")
@ConditionalOnProperty(prefix = "app.config.outside", name = "prop", havingValue = "b") //how to add second?
public SomeBean beanForPropB() {
return new SomeBean2();
}
and application.yaml
app:
config:
inside:
prop: a
outside:
prop: b
I want to register the beans based on if any of the inside/outside props have "a" or "b" as their value. Currently spring does not allow two @ConditionalOnProperty
on the same bean. So any ideas how to go about this?
I am open to changing the application.yaml file to a slightly different format if that makes the code side of things easier but would ideally keep it the same.
Is there any way to use @ConditionalOnProperty twice for the same bean?
I have two properties, that are mapped to "A" or "B" individually.
Spring configuration:
@Bean
@ConditionalOnProperty(prefix = "app.config.inside", name = "prop", havingValue = "a")
@ConditionalOnProperty(prefix = "app.config.outside", name = "prop", havingValue = "a") //??
public SomeBean beanForPropA() {
return new SomeBean1();
}
@Bean
@ConditionalOnProperty(prefix = "app.config.inside", name = "prop", havingValue = "b")
@ConditionalOnProperty(prefix = "app.config.outside", name = "prop", havingValue = "b") //how to add second?
public SomeBean beanForPropB() {
return new SomeBean2();
}
and application.yaml
app:
config:
inside:
prop: a
outside:
prop: b
I want to register the beans based on if any of the inside/outside props have "a" or "b" as their value. Currently spring does not allow two @ConditionalOnProperty
on the same bean. So any ideas how to go about this?
I am open to changing the application.yaml file to a slightly different format if that makes the code side of things easier but would ideally keep it the same.
Share Improve this question asked Mar 31 at 20:37 kawikawikawikawi 92 bronze badges 7 | Show 2 more comments1 Answer
Reset to default 1@ConditionalOnExpression can be used in this way to achieve condition X or condition Y but not both. I tested this code with the same application.yaml provided.
@Bean
@ConditionalOnExpression("#{('${app.config.inside.prop}' == 'a' && '${app.config.outside.prop}' != 'a') || ('${app.config.inside.prop}' != 'a' && '${app.config.outside.prop}' == 'a')}")
public CustomBean customInsideOrOutsideNotBoth() {
System.out.println("app.config.inside _or_ app.config.outside _not_ both");
return new CustomBean();
}
Update:
I have tested and tried this code:
// Better readability:
@ConditionalOnExpression(
"#{" +
"('${app.config.inside.prop}' == 'a' && " +
"'${app.config.outside.prop}' != 'a') " +
"|| " +
"('${app.config.inside.prop}' != 'a' && " +
"'${app.config.outside.prop}' == 'a')" +
"}"
)
public SomeBean beanForPropA() {
System.out.println("Some bean1 is in beanForPropA.");
return new SomeBean1();
}
Here is the repository to test the code.
The explanation for not being able to apply @ConditionalOnProperty twice on the same method appears to be:
@ConditionalOnProperty is not marked with the @Repeatable annotation and is not designed to be repeatable.
Applying the same annotation to a declaration without first declaring it to be repeatable results in a compile-time error.
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional({OnPropertyCondition.class})
public @interface ConditionalOnProperty {
String[] value() default {};
String prefix() default "";
String[] name() default {};
String havingValue() default "";
boolean matchIfMissing() default false;
}
@ConditionalOnExpression
annotation instead. – Je Campos Commented Mar 31 at 21:13@ConditionalOnExpression
see this. – Lee Greiner Commented Mar 31 at 21:39