44

I need to check that two conditions are satisfied on a YAML property file, while creating a bean. How do I do that, as the @ConditionalOnProperty annotation supports only one property?

Ortomala Lokni
  • 56,620
  • 24
  • 188
  • 240
Zenith Kenneth
  • 493
  • 1
  • 5
  • 6
  • Possible duplicate of [Spring Boot SpEL ConditionalOnExpression check multiple properties](https://stackoverflow.com/questions/40477251/spring-boot-spel-conditionalonexpression-check-multiple-properties) – Piran May 04 '18 at 09:43

5 Answers5

45

Use @ConditionalOnExpression annotation and SpEL expression as described here http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html.

Example:

@Controller
@ConditionalOnExpression("${controller.enabled} and ${some.value} > 10")
public class WebController {
Navrocky
  • 1,670
  • 1
  • 13
  • 10
44

Since from the beginning of @ConditionalOnProperty it was possible to check more than one property. The name / value attribute is an array.

@Configuration
@ConditionalOnProperty({ "property1", "property2" })
protected static class MultiplePropertiesRequiredConfiguration {

    @Bean
    public String foo() {
        return "foo";
    }

}

For simple boolean properties with an AND check you don't need a @ConditionalOnExpression.

Ortomala Lokni
  • 56,620
  • 24
  • 188
  • 240
Josh
  • 869
  • 10
  • 10
13

You might be interested in the AllNestedConditions abstract class that was introduced in Spring Boot 1.3.0. This allows you to create composite conditions where all conditions you define must apply before any @Bean are initialized by your @Configuration class.

public class ThisPropertyAndThatProperty extends AllNestedConditions {

    @ConditionalOnProperty("this.property")
    @Bean
    public ThisPropertyBean thisProperty() {
    }

    @ConditionalOnProperty("that.property")
    @Bean
    public ThatPropertyBean thatProperty() {
    }

}

Then you can annotate your @Configuration like this:

@Conditional({ThisPropertyAndThatProperty.class}
@Configuration
Dan Oak
  • 704
  • 1
  • 7
  • 26
Patrick Grimard
  • 7,033
  • 8
  • 51
  • 68
  • 1
    `AllNestedCondition` has no no-arg constructor. You need to call super constructor from `ThisPropertyAndThatProperty` constructor like `super(ConfigurationPhase.PARSE_CONFIGURATION)`. – Abhijit Sarkar Mar 05 '21 at 02:33
4
@ConditionalOnExpression("#{${path.to.property.one:true} and ${path.to.property.two:true}}")

both true values are the default value if property is not found.

Sachith Deshan N
  • 160
  • 4
  • 14
-6

Resolved the issue by using @ConditionalOnExpression for the two properties together.

@ConditionalOnExpression("'${com.property1}${com.property2}'=='value1value2'")

Wherein property value in configuration is as below.

Property 1 Name - com.property1 Value - value1

Property 2 Name - com.property2 Value - value2

Zenith Kenneth
  • 493
  • 1
  • 5
  • 6
  • 8
    What about `"${com.property1}=='value1' and ${com.property2}=='value2'"` ? – Navrocky Oct 06 '16 at 08:51
  • 6
    counter-example: `com.property = value` and `com.property2 = 1value2` make the expression == true but is not what the OP is looking for. 95% of the code of applications around the world suck because of this kind of ugly hacks that only bring trouble. As @Navrocky said, the correct solution would be `"${com.property1}=='value1' and ${com.property2}=='value2'"` – Clint Eastwood Apr 09 '18 at 19:43