Spring Boot and multiple external configuration files

nir picture nir · Sep 15, 2014 · Viewed 427.4k times · Source

I have multiple property files that I want to load from classpath. There is one default set under /src/main/resources which is part of myapp.jar. My springcontext expects files to be on the classpath. i.e.

<util:properties id="Job1Props"
    location="classpath:job1.properties"></util:properties>

<util:properties id="Job2Props"
    location="classpath:job2.properties"></util:properties>

I also need the option to override these properties with an external set. I have an external config folder in cwd. As per spring boot doc config folder should be on classpath. But its not clear from doc if it will only override the applicaiton.properties from there or all the properties in config.

When I tested it, only application.properties gets picked up and rest of properties are still picked up from /src/main/resources. I have tried supplying them as comma separated list to spring.config.location but the default set is still not being overriden.

How do I make mulitiple external config files override default ones?

As workaround I currently used app.config.location (app specific property) which I supply through the command line. i.e

java -jar myapp.jar app.config.location=file:./config

and I changed my applicationcontext to

<util:properties id="Job2Props"
    location="{app.config.location}/job2.properties"></util:properties>

And this is how I make separation between file and classpath while loading Application.
EDITS:

//psuedo code

if (StringUtils.isBlank(app.config.location)) {
            System.setProperty(APP_CONFIG_LOCATION, "classpath:");
}

I would really like not to use the above workaround and have spring override all external config files on the classpath like it does for the application.properties file.

Answer

M. Deinum picture M. Deinum · Sep 16, 2014

UPDATE: As the behaviour of spring.config.location now overrides the default instead of adding to it. You need to use spring.config.additional-location to keep the defaults. This is a change in behaviour from 1.x to 2.x


When using Spring Boot the properties are loaded in the following order (see Externalized Configuration in the Spring Boot reference guide).

  1. Command line arguments.
  2. Java System properties (System.getProperties()).
  3. OS environment variables.
  4. JNDI attributes from java:comp/env
  5. A RandomValuePropertySource that only has properties in random.*.
  6. Application properties outside of your packaged jar (application.properties including YAML and profile variants).
  7. Application properties packaged inside your jar (application.properties including YAML and profile variants).
  8. @PropertySource annotations on your @Configuration classes.
  9. Default properties (specified using SpringApplication.setDefaultProperties).

When resolving properties (i.e. @Value("${myprop}") resolving is done in the reverse order (so starting with 9).

To add different files you can use the spring.config.location properties which takes a comma separated list of property files or file location (directories).

-Dspring.config.location=your/config/dir/

The one above will add a directory which will be consulted for application.properties files.

-Dspring.config.location=classpath:job1.properties,classpath:job2.properties

This will add the 2 properties file to the files that are loaded.

The default configuration files and locations are loaded before the additonally specified spring.config.location ones meaning that the latter will always override properties set in the earlier ones. (See also this section of the Spring Boot Reference Guide).

If spring.config.location contains directories (as opposed to files) they should end in / (and will be appended with the names generated from spring.config.name before being loaded). The default search path classpath:,classpath:/config,file:,file:config/ is always used, irrespective of the value of spring.config.location. In that way you can set up default values for your application in application.properties (or whatever other basename you choose with spring.config.name) and override it at runtime with a different file, keeping the defaults.