physi
physi

Reputation: 151

spring-boot application.properties are not overwriten

I have one class:

package com.example.propertyorder;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@SpringBootApplication
@PropertySource(value="file:C:\\TEMP\\property-order.properties", ignoreResourceNotFound = true)

public class PropertyOrderApplication {


    public static void main(String[] args) {

        ConfigurableApplicationContext run = SpringApplication.run(PropertyOrderApplication.class, args);
        Environment env = (Environment) run.getBean("environment");
        System.out.println(env.getProperty("my.value"));
        System.out.println(env.getProperty("my.value2"));
    }
}

and I have one application.properties file:

my.value=application.properties

and I have my external properties file C:\\TEMP\\property-order.properties:

my.value=property-order.properties
my.value2=gotcha

but the result is always:

application.properties
gotcha

instead of:

property-order.properties
gotcha

So it looks like, that spring-boot's application.properties overrules all. Is there a way to fix it. The only solution that i found is to not use the application.properties, but a my-app.properties instead and place that one before my external file in the ProperySource-tree:

@PropertySource(value="classpath:my-app.properties")
@PropertySource(value="file:C:\\TEMP\\property-order.properties", ignoreResourceNotFound = true)

Is there a better way, so that I can stay with the application.properties ?

edit:

added missing value2 to the property file

Upvotes: 0

Views: 964

Answers (2)

davidxxx
davidxxx

Reputation: 131324

The actual behavior is conform to the Spring Boot documentation :

Spring Boot uses a very particular PropertySource order that is designed to allow sensible overriding of values. Properties are considered in the following order:

....

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.

The application.properties (inside or outside the jar) have a higher priority (14 and 15 respectively) than any @PropertySource annotations added in @Configuration class (16).

Is there a better way, so that I can stay with the application.properties ?

Of course you can use any of the 13 higher priority ways :

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. Command line arguments.

4.Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).

5.ServletConfig init parameters.

6.ServletContext init parameters.

7.JNDI attributes from java:comp/env.

8.Java System properties (System.getProperties()).

9.OS environment variables.

10.A RandomValuePropertySource that has properties only in random.*.

11.Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).

12.Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).

13.Application properties outside of your packaged jar (application.properties and YAML variants).

For example renaming property-order.properties to application-order.properties to make it a Spring Boot profile properties and run your application with order as active profile would give it a higher priority and so it should be enough :

@SpringBootApplication
public class PropertyOrderApplication {...}

Upvotes: 2

Ishant Gaurav
Ishant Gaurav

Reputation: 1203

If you want to override the property defined int the application.properties, you can use the below approach.

@PropertySources({
        @PropertySource(value = "classpath:application.properties"),
        @PropertySource(value = "file:/user/home/external.properties", ignoreResourceNotFound = true)
})
public class Application {
    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

    }


}

Upvotes: 1

Related Questions