Search code examples
javaspringspring-bootspring-config

What is the loading precedence for properties from Spring Cloud Config?


Spring has an explicit order for the loading of externalized configurations.

  1. Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
  2. @TestPropertySource annotations on your tests.
  3. @SpringBootTest#properties annotation attribute on your tests.
  4. Command line arguments.
  5. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
  6. ServletConfig init parameters.
  7. ServletContext init parameters.
  8. JNDI attributes from java:comp/env.
  9. Java System properties (System.getProperties()).
  10. OS environment variables.
  11. A RandomValuePropertySource that has properties only in random.*.
  12. Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
  13. Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
  14. Application properties outside of your packaged jar (application.properties and YAML variants).
  15. Application properties packaged inside your jar (application.properties and YAML variants).
  16. @PropertySource annotations on your @Configuration classes.
  17. Default properties (specified by setting SpringApplication.setDefaultProperties).

However, there seems to be a glaring omission for configurations coming from Spring Cloud Config. Does anyone know where Spring Cloud Config fit above


Solution

  • As others have stated, the config-server comes first. If you are trying to override the config-server's properties with local properties (i.e. application-local.yml), then you need to add two properties to the config-server**:

    spring.cloud.config.allowOverride=true
    spring.cloud.config.overrideNone=true
    

    Per the documentation:

    The property sources that are added to you application by the bootstrap context are often "remote" (e.g. from a Config Server), and by default they cannot be overridden locally. If you want to allow your applications to override the remote properties with their own System properties or config files, the remote property source has to grant it permission by setting spring.cloud.config.allowOverride=true (it doesn’t work to set this locally). Once that flag is set there are some finer grained settings to control the location of the remote properties in relation to System properties and the application’s local configuration: spring.cloud.config.overrideNone=true to override with any local property source, and spring.cloud.config.overrideSystemProperties=false if only System properties and env vars should override the remote settings, but not the local config files.

    Also see this, regarding using spring.cloud.config.override-system-properties=false to override via system / command line properties. The documentation quoted above had/has an inconsistency, which I removed from the quote.

    Note, if you want the remote config server to override your local properties file sources but not your local system properties or environment properties, add the following in the config server:

    spring.cloud.config.allowOverride=true
    spring.cloud.config.overrideNone=false
    spring.cloud.config.overrideSystemProperties=false
    

    ** In this case the overrideSystemProperties value is ignored. See org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration#insertPropertySources

    Note: All the above applies to Spring Boot 2.3.x. Version 2.4.x uses an alternate loading priority. See https://github.com/spring-cloud/spring-cloud-config/issues/1856