最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - @ConditionalOnProperty how to use twice on the same bean? - Stack Overflow

programmeradmin3浏览0评论

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
  • Try using @ConditionalOnExpression annotation instead. – Je Campos Commented Mar 31 at 21:13
  • read the api, name takes a string array docs.spring.io/spring-boot/3.3/api/java//springframework/… – Toerktumlare Commented Mar 31 at 21:15
  • For more info on @ConditionalOnExpression see this. – Lee Greiner Commented Mar 31 at 21:39
  • @Toerktumlare Javadoc says "If multiple names are specified, all of the properties have to pass the test for the condition to match." which is not what is asked for. – Lesiak Commented Mar 31 at 21:42
  • 1 One way is to use AnyNestedCondition. See baeldung/… – Lesiak Commented Mar 31 at 21:46
 |  Show 2 more comments

1 Answer 1

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;
}
发布评论

评论列表(0)

  1. 暂无评论