8

I specified Spring properties inside the application.properties file. How can i populate those properties from the environment variables?

Here is what I tried, but it doesn't seem to work:

application.properties

spring.datasource.url=jdbc:postgresql://#{ systemProperties['DATABASE_HOST']}:5432/dbname
spring.datasource.username = postgres
spring.datasource.password = postgres
Oleg
  • 2,984
  • 8
  • 43
  • 71
  • Possible duplicate of [Using env variable in Spring Boot's application.properties](https://stackoverflow.com/questions/35531661/using-env-variable-in-spring-boots-application-properties) – Alex R Oct 11 '18 at 02:47

3 Answers3

9

You can refer to environment properties in the same way you refer to Spring properties using ${...} syntax.

In your case:

spring.datasource.url=jdbc:postgresql://${DATABASE_HOST}:5432/dbname
Maciej Walkowiak
  • 12,372
  • 59
  • 63
  • 2
    I have an environment variable name: user and value: pass. In my application.properties I used datasource.username=${user}. It does not read the value – JayC Feb 23 '17 at 20:58
  • 1
    Is there any way to set the default value in case environment variable is not set? – Ganesh Satpute Nov 10 '17 at 08:50
  • You can put default values to application.yml. env properties overwrite them. They have higher priority – Maciej Walkowiak Nov 10 '17 at 19:28
3

Out of the box, as you know, spring-boot expects its Datasource details to be using a specific set of variable names. Being spring of course you can rework this if you need by a few methods:

1/ If the need to use variables from the environment comes from deployment to a cloud service such as Cloud Foundry or Horuku, there is spring-boot-starter-cloud-connector which handles allot of the plumbing out of the box. A good read is the (Binding to Data Services with Spring Boot in Cloud Foundry article and the Deploying to the cloud docs which walks you thru this

2/ Instead of relying on Spring-Boot's own auto-magical wiring mechanism, you can create a custom configuration bean to override how the DataSource information is populated. A good read explaining the annotations involved can be found here: Spring Java Config Documentation - @Bean Configuration JavaDOC. Based on your example above, here is what I spat out:

@Configuration
public class MyDataSourceConfig {

    @Bean
    @Primary
    public DataSource getDataSource() {

        String url = "jdbc:postgresql://" + System.getenv("DATABASE_HOST") + ":5432/dbname";
        String username = "postgres"; 
        String password = "postgres";
        String driverClassName = "org.postgresql.Driver";

        /*
         * Create the datasource and return it
         * 
         * You could create the specific DS 
         * implementation (ie: org.postgresql.ds.PGPoolingDataSource) 
         * or ask Spring's DataSourceBuilder to autoconfigure it for you, 
         * whichever works best in your eyes
        */

        return DataSourceBuilder
                .create()
                .url( url )
                .username( username )
                .password( password )
                .driverClassName( driverClassName )
                .build();
    }
}

Just remember that in spring, you can always override allot of the default behaviours with a little bit of digging!

Hope this helps!

Eric G
  • 124
  • 6
2

You don't have to. When Spring Boot initializes its environment, it pulls stuff from both the application.properties file and any system-level variables and combines them together. The full list of locations where Spring takes them from is here, specifically points 9) and 10).

rorschach
  • 2,871
  • 1
  • 17
  • 20
  • thats nice, but in that case I can't use my own property names (which I have to due to the setup here) – Oleg Sep 26 '16 at 13:02
  • Just shift them around and assign `DATABASE_HOST` to `SPRING_DATASOURCE_URL` and so forth – rorschach Sep 26 '16 at 13:04