Spring Boot - ConditionalOnExpression with property from outside sources

Viewed 387

I am trying to create a bean only when my property conditions are met, and using the Spring Boot annotation @ConditionalOnExpression for it. The properties which I am using inside the expression are fetched from outside sources (e.g. database or cloud), and are not defined in the properties file inside my application code. This is not working. But it works when I define the same properties inside a properties file.

My setup is as follows:

  1. My application uses properties from both an internal property file, and some external sources.
  2. Using PropertyPlaceholderConfigurer I have loaded the properties from all sources, and they are available using the @Value annotation.
  3. My sample class:
@Component
@ConditionalOnExpression("${property1.enabled:false}")
public class PropertyIsEnabledClass {

    @Value("${property1.enabled:false}")
    private boolean isProperty1Enabled;
    
    public SomeClass(@Value("${property1.enabled:false}") consInputIsProperty1Enabled) {
        System.out.println("PropertyIsEnabledClass Constructor: consInputIsProperty1Enabled - " + consInputIsProperty1Enabled);
        System.out.println("PropertyIsEnabledClass Constructor: isProperty1Enabled - " + this.isProperty1Enabled);
    }

    @PostConstruct
    public void init() {
        System.out.println("PropertyIsEnabledClass PostConstruct: isProperty1Enabled - " + this.isProperty1Enabled);
    }
}

@Component
@ConditionalOnExpression("not ${property1.enabled:false}")
public class PropertyIsNotEnabledClass {

    @Value("${property1.enabled:false}")
    private boolean isProperty1Enabled;
    
    public SomeClass(@Value("${property1.enabled:false}") consInputIsProperty1Enabled) {
        System.out.println("PropertyIsNotEnabledClass Constructor: consInputIsProperty1Enabled - " + consInputIsProperty1Enabled);
        System.out.println("PropertyIsNotEnabledClass Constructor: isProperty1Enabled - " + this.isProperty1Enabled);
    }

    @PostConstruct
    public void init() {
        System.out.println("PropertyIsNotEnabledClass PostConstruct: isProperty1Enabled - " + this.isProperty1Enabled);
    }
}

In the above, when the property is defined as true in the external datasource and not in internal properties file, the bean PropertyIsEnabledClass is not created, and it prints:

PropertyIsNotEnabledClass Constructor: consInputIsProperty1Enabled - true
PropertyIsNotEnabledClass Constructor: isProperty1Enabled - false
PropertyIsNotEnabledClass PostConstruct: isProperty1Enabled - true

However, when I define the property as true in the internal properties file, it prints:

PropertyIsEnabledClass Constructor: consInputIsProperty1Enabled - true
PropertyIsEnabledClass Constructor: isProperty1Enabled - true
PropertyIsEnabledClass PostConstruct: isProperty1Enabled - true

Please help me understand if this is a valid behavior, or some issue in which I am loading the properties -

  1. That the SPEL requires the properties to be defined inside properties file, and not in external datasource.
  2. The property is set after the bean is created. Hence available in the PostConstruct method, but not in Constructor.
  3. The property is however available always through the @Value annotation.

Thanks.

0 Answers
Related