1

I want to have Spring load an external configuration file if present and else use the once provided in src/main/resources.

Current setup:

src/main/resources/application.properties
src/main/resources/application-dev.properties
src/main/resources/application-prod.properties

/this/is/an/external/dir/application-dev.properties

Similar to https://stackoverflow.com/a/27776123/5126654 I added the following annotations:

@EnableFeignClients
@SpringBootApplication
@EnableEncryptableProperties
@PropertySources({ //
    @PropertySource("classpath:application.properties"), //
    @PropertySource(value = "file:${external.config}", ignoreResourceNotFound = true) //
})
public class Application extends SpringBootServletInitializer {

   // ....
}

And have the following entry in my application.properties:

external.config=/this/is/an/external/dir/application-dev.properties

I also can see that the external conifguration file is picked up. The problem I have is that every entry in the classpath properties file overwrites the external ones. I.e. instead of taking entries from /this/is/an/external/dir/application-dev.properties entries from src/main/resources/application-dev.properties are taken.

How can I modify my code such that the external file overrides the entries of the classpath file?

Stephan Stahlmann
  • 441
  • 2
  • 5
  • 19

3 Answers3

0

Just change the order of importing. Something like:

<context:property-placeholder file-encoding="UTF-8"
                            location="${YOUR_CUSTOM_PATH}/global.properties ,
                                      ${YOUR_CUSTOM_PATH}/local.properties" ignore-unresolvable="true"/>

or

@PropertySource(value = {"classpath:global.properties" , "local.properties"},ignoreResourceNotFound = true)

In this case the local.properties overrides properties of global.properties

  • Not really working for me.. I think the problem is (for me) is the ordering of the resolution: https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config I have the same properties in the external file and src/main/resource file. For development I want the /src/main/resources file. But for a build application I want to have the application-dev.properties in an external location. – Stephan Stahlmann Jul 20 '20 at 12:30
  • This could be a good resource for differentiating development and production environments https://spring.io/blog/2020/04/23/spring-tips-configuration – MohammadGhoreishi Jul 21 '20 at 05:56
0

Since you only want the external config for development, you could as well consider setting external property source as a command line argument in the IDE run configuration for your project.

--spring.config.location=/this/is/an/external/dir/application-dev.properties

The property source specified in the above manner overrides the application.properties present in class path.

Harshith
  • 58
  • 5
0

I want to have Spring load an external configuration file if present and else use the once provided in src/main/resources.

That's the default behavior of Spring Boot. So you just need to enable it correctly.

First of all, remove next annotations, they may disrupt/override the default mechanism:

@PropertySources({ //
    @PropertySource("classpath:application.properties"), //
    @PropertySource(value = "file:${external.config}", ignoreResourceNotFound = true) //
})

Then specify location of your file as a command line argument:

java -jar myapp.jar --spring.config.additional-location=/this/is/an/external/dir/

More information here:

Then either rename your config to application.properties or specify your dev profile (suffix in your file name) via another environmental variable:

-Dspring-boot.run.profiles=dev

Related question: Setting active profile and config location from command line in spring boot

stepio
  • 865
  • 2
  • 9
  • 22