I have come across some behaviour which seems inconsistent in how spring boot handles environment variables in application properties files vs configuration property classes. I am unsure whether this is a bug in spring or an error in my understanding of what "ought" to happen.
I have
@Data
@ConfigurationProperties("foo")
@Validated
public class ClientProperties {
@NotBlank
private String apiKey;
@NotBlank
private String uri;
}
In the application.properties
file I have:
foo.baseUri=https://system.appspot.com
foo.uri=${foo.baseUri}/Valuation?apikey=${foo.apiKey}&bar={bar}
Setting Just FOO_APIKEY
If I run my app with:
export FOO_APIKEY=DEF
Then I get
APPLICATION FAILED TO START
***************************
Description:
Binding to target class ClientProperties(apiKey=null, uri=https://system.appspot.com/Valuation?apikey=DEF&bar={bar}) failed:
Property: foo.apiKey
Value: null
Reason: may not be empty
Note that in the URI the api key is set as expected as well as the base URI
Setting Just FOO_API_KEY
Next, if instead, I try to set just this property (remove the old env var):
export FOO_API_KEY=ABC
Then my app starts, but the values are not as expected. My logs show:
API Key: ABC.
URI Property: ${foo.baseUri}/Insurance?apikey=${foo.apiKey}&bar={bar}.
Note that now the base uri also disappeared as well as the API key being missing.
Setting Both Properties FOO_API_KEY and FOO_APIKEY
When I set both environment variables the app starts but the apiKey
property of ClientProperties
holds the value of the FOO_APIKEY
export, where as the uri
property of ClientProperties
holds the value of the FOO_API_KEY
export.
API KEY IS: ABC.
URI IS: https://system.appspot.com/Insurance?apikey=DEF&bar={bar}.
Notes
I actually don't need the value from ClientProperties.apiKey
. It's only ever used in the app via the ClientProperties.uri
which is already being resolved in application.properties
. However, I specify the property so that I can have validation to ensure the value gets set. I could remove the value from my class and everything would be ok - expect then I lose my validation.
Spring boot version is: 1.5.10.RELEASE