Hi team,

today I found some unexpected behavior when trying to override a spring property via Environment variable. I created a project that shows this behavior:

According to the documentation it is possible to override the spring properties via environment variables following these roles:

  • Replace dots (.) with underscores (_).
  • Remove any dashes (-).
  • Convert to uppercase.

This project has the following yaml file:

spring:
  datasource:
    data-input:
      jdbc:
        url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
        driverClassName: wrongValue
        username: sa
        password: password

To override the driverClassName following the above rule, we should set the environment variable SPRING_DATASOURCE_DATAINPUT_JDBC_DRIVERCLASSNAME

However, this is not the case. As show in the test the Environment object won't return the overridden value by SPRING_DATASOURCE_DATAINPUT_JDBC_DRIVERCLASSNAME. Interestingly, the driver is correctly set in the DataSource where property are bound via the @ConfigurationProperties annotation.

The opposite scenario happens when is the SPRING_DATASOURCE_DATA_INPUT_JDBC_DRIVERCLASSNAME to being set. In this case the DataSource initialization will fail because the driver value is incorrect (wrongValue), while the Environment will return the value set via the environment variable. Comment the @Bean annotation in the App.java file and line 27 in DynamicPropertyInjectionIT.java file. Tests are now green!

So not only I had to follow different rules to override the spring property via environment variables but I also found inconsistency between how environment variables are bound via @ConfigurationProperties and @ConditionalOnProperty (and other related annotation like @ConditionalOnExpression).