How to create custom condition similar to "@ConditionalOnProperty" without using spring-boot?

Viewed 435

I am trying to create a custom condition using spring context.

  • I am using spring-context 5.3.13 (no spring-boot)
  • I have a file named "config.yaml" under "src/main/resources"
  • I have this @PropertySource custom configured: @PropertySource(value = "classpath:config.yaml", factory = TypesafeAdapterPropertySourceFactory.class)
  • I am trying to get a property from inside a custom spring Condition:
public class MyConditionalOnProperty implements ConfigurationCondition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // just to test what property sources are present
        for(Iterator it = ((AbstractEnvironment) context.getEnvironment()).getPropertySources().iterator(); it.hasNext(); ) {
            PropertySource propertySource = (PropertySource) it.next();
            System.out.println(propertySource.getName());
            //prints only "systemProperties" and "systemEnvironment"
        }
        
        return context.getEnvironment().containsProperty("my.prop");
    }

    @Override
    public ConfigurationPhase getConfigurationPhase() {
        return ConfigurationPhase.REGISTER_BEAN;
    }
}
  • my.prop is present after the application context was loaded
  • I have a bean annotated with the condition:
@Named
@Singleton
@Conditional(PropertyEnabledCondition.class)
public class MyTestBean {

}

I have also debugged and found that my custom property source are loaded only after this stage.

Is there a way to retrieve application properties in condition or recreate @ConditionalOnProperty without using spring-boot some other way?

1 Answers

The issue was that my @PropertySource annotations were directly on my app's main configuring class but on a different configuration. This means that they were processed only after the beans were registered.

So if you initiate your context like so:

var context = new AnnotationConfigApplicationContext(SpringConfig.class);

make sure you have your @PropertySource annotated on SpringConfig.java directly

Related