spring-boot: Need the ability to conditional add configuration when a property is missing.

I have a use case where I only want to configure beans if and ONLY if a given property is NOT present within the environment.

I was using @ConditionalOnProperty and setting matchOnMissing = true. And this condition evaluates to “true” when the property is missing OR the property is present and has any value other than “false”.

I either need a new annotation @ConditionalOnMissingProperty or a new configuration option added to @ConditionalOnProperty that allows “only match if not present”

I was able to work around this issue with @ConditonalOnExpression but this ended up being quite tricky because the property I was testing for was an MSSQL server jdbc url…which had "" in it…

The parser was replacing my variable with the jdbc URL and then re-evaluating the expression which ended up with a syntax error on the backslash. The solution was to enclose my environment property in single quotes to get around this parsing error but then I am evaluating string literals. This ended up being a lot more complicated than it should have been.

so if the property is absent, I end up with a string literal “true”…ugh.

    @Configuration
    @ConditionalOnExpression("'${datasource.reporter.url:true}' == 'true'")
    protected static class AliasReporterDataSourceConfig {

If you have a preference on an approach I could take a stab at a pull request for this.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 9
  • Comments: 15 (4 by maintainers)

Most upvoted comments

This is an old thread, but maybe this can be useful for other people. We had a similar issue and the solution adopted by my team was creating a custom condition:

    public class DataSourceReportMissingCondition implements Condition {
        @Override
        public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) {
            return !context.getEnvironment().containsProperty("MY_PROPERTY_NAME");
        }
    }

Our use case:

We have two data sources: A primary data source that is used by most of the application for transactional workflows and reporter data source that is used to run reports on a slightly older version of the “Real” database. The reporter works on a replicated copy of the primary data source and allows more intensive reports to be run without impacting the transactional work in the primrary data source. This replication is only done in our larger environments and in cases where there is only one active database, we want the reporter data source to just be an alias to the primary data source.

So the configuration of the reporter data source is based on if a reporter database url is present in the application configuration. If it is, we create a new separate data source, if it is not we create a single data source and provide two aliases (primary and reporter).

I agree with Andy, that having a new @ConditionalOnMissingProperty is more clear then mangling the @ConditionalOnProperty. We did come up with a work-around using @ConditionalOnExpressionand I opened this issue more as a “Ease of Use” enhancement.