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
).