Search code examples
javaspringspring-el

Spring value injection - if no env variable then default to system property from file


I am looking for a neat way of injecting values from environment variables to pojo, but with default values for not set env variables. I know about this syntax:

@Value("#{systemProperties['JDBC_CONNECTION_STRING'] ?: \"jdbc:mysql://localhost:3306/mydb?user=root\"}")

But it means that I have to hardcode defaults in java files. And I would prefer to have it in properties file. Is it possible?

I need this because on AWS EBS env variables are only way to pass properties but we don't deploy only there. On other places I want to read props from file.


Solution

  • In your spring.xml config file you add the following:

    <context:property-placeholder order="-50"/>
    

    And then

    <context:property-placeholder order="0" location="classpath:x.y.z/application.properties"/>      
    

    The first property-placholder will load all the values from system properties and the second will load from a properties file.

    Notice how the order for the system properties one less than the application properties one so the system properties will take precedence.

    Now in your class files you simply do this:

    @Value("${JDBC_CONNECTION_STRING}")
    private String jdbcConnectionString
    

    And it will inject the value from system properties if present and from application properties if it is not in system properties.

    What I also like to do is have another properties file which I load from S3 whose order is between the above two so I can override the default.