Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I am using a combination of @PropertySource and @ConfigurationProperties but I want to overwrite them with an external properties file

I have built a spring boot project.

Within it, I have a properties class that looks like this:

@Configuration
@PropertySource(value = "classpath:abc.properties")
@ConfigurationProperties
public class ABCProperties {

    private Map<String, String> someUrls;

    @Bean
    public Map<String, String> someUrls() {
        return someUrls;
    }

    public Map<String, String> getSomeUrls() {
        return someUrls;
    }

    public void setSomeUrls(Map<String, String> someUrls) {
        this.someUrls = someUrls;
    }
}

The contents of the abc.properties file look like this:

someUrls.urlA=someURL
someUrls.urlB=someOtherURL

Within the project, in the resources folder (and test resources folder), I have provided an abc.properties file. Once built and run, the program can access the properties in the abc.properties file as expected (also can be accessed correctly in tests) - they map nicely to my url map.

So far so good.

However, the URLs to which I'm referring in the properties class aren't always the same. In some deployments, I want to overwrite them. With properties that are specified in my application.properties file, this is easy; simply having another, external application.properties file in the same (root) folder from which I've run the application will overwrite any properties that I put in it automatically.

What I would like to do is sometimes also put an external abc.properties file in the application's root folder and have it overwrite the abc.properties properties in the same way. Of course I tried this, but the properties from the abc.properties file that is built into the jar are retained and not overwritten. In fact, I'm not sure that the spring boot program recognises that there is another, external abc.properties file in its root folder at all.

I have read seemingly endlessly about how to achieve this without success. I have also tried specifying the following in my application.properties but it has made no difference (it also wouldn't be ideal even if it did work, because I'd rather not specify the direct path in all circumstances).

spring.config.location=/path/to/application/root/
spring.config.name=abc.properties

If I had to guess, the problem is that in the properties class I am pointing to 'classpath:..' and the external file is not actually on the classpath because it's.... well external.

but spring boot knows how to look in its root application folder for an overwriting application.properties so I'm hoping it is also able to look for other properties files to overwrite? I just cannot fathom how to achieve this.

and yes, I specifically want my properties in this abc.properties file rather than in the application properties.

like image 239
Daisy Day Avatar asked Oct 31 '17 18:10

Daisy Day


People also ask

How do you override a Spring Boot property?

To override your Spring Boot application properties when it's running on Kubernetes, just set environment variables on the container. To set an environment variable on a container, first, initialise a ConfigMap containing the environment variables that you want to override.

How do you externalize a constants from a Spring configuration file into a properties file?

You can use properties files, YAML files, environment variables and command-line arguments to externalize configuration. Property values can be injected directly into your beans using the @Value annotation, accessed via Spring's Environment abstraction or bound to structured objects.

Does Spring Boot allows you to externalize your configuration so you can work with the same application code in different environments?

Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments. You can use properties files, YAML files, environment variables, and command-line arguments to externalize configuration.

Can we have two application properties in Spring Boot?

Spring Boot supports different properties based on the Spring active profile. For example, we can keep two separate files for development and production to run the Spring Boot application.


1 Answers

Have you looked into PropertySources?

@PropertySources({
    @PropertySource("classpath:abc.properties"),
    @PropertySource(value="file:abc.properties", ignoreResourceNotFound=true)
})

From their doc:

In cases where a given property key exists in more than one .properties file, the last @PropertySource annotation processed will 'win' and override.

Basically what you are saying here: load abc.properties from classpath, but also load abc.properties from this external location, just ignore the latter if it doesn't find it. It should override the properties you declared in the external file.

Haven't tested this, so hope it works out.

like image 84
Andrei Sfat Avatar answered Sep 22 '22 22:09

Andrei Sfat