The Externalized Configuration section of the reference documentation say that order of default properties (SpringApplication.setDefaultProperties()) is lower with @PropertySource, but my test is inconsistent.

My Spring Boot is 2.6.7.


My Test 1

@SpringBootApplication
@PropertySource(value = "classpath:/api.properties")
public class Demo6Application {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Demo6Application.class);
        Properties properties = new Properties();
        properties.setProperty("api.name","default");
        application.setDefaultProperties(properties);
        ConfigurableApplicationContext run = application.run(args);
        String property = run.getEnvironment().getProperty("api.name");
        System.out.println(String.format("api.name=%s",property));
    }

}

api.properties api.name=api

My Result 1

api.name=default


api.properties may be not loaded in My Test 1,so I print PropertySources of Environment in console.


My Test 2

@SpringBootApplication
@PropertySource(value = "classpath:/api.properties")
public class Demo6Application {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Demo6Application.class);
        Properties properties = new Properties();
        properties.setProperty("api.name","default");
        application.setDefaultProperties(properties);
        ConfigurableApplicationContext run = application.run(args);
        run.getEnvironment().getPropertySources().forEach(System.out::println);
    }

}

My Result 2

ConfigurationPropertySourcesPropertySource {name='configurationProperties'}
PropertiesPropertySource {name='systemProperties'}
OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}
RandomValuePropertySource {name='random'}
CachedRandomPropertySource {name='cachedrandom'}
MapPropertySource {name='springCloudClientHostInfo'}
DefaultPropertiesPropertySource {name='defaultProperties'}
ResourcePropertySource {name='class path resource [api.properties]'}

My Thought

Spring Boot 2.4 before, the order is achieved by ConfigFileApplicationListener$PropertySourceOrderingPostProcessor, but Spring Boot 2.4 after, I cannot find a BeanFactoryPostProcessor to do that.

Comment From: wilkinsona

Thanks for the report. This looks like a bug to me. The defaultProperties property source is moved to the end by ConfigDataEnvironment:

https://github.com/spring-projects/spring-boot/blob/ef03bb8aa22a903a0a0ba5d1c4fbd7fcb847e651/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java#L331

However, this happens before Framework's ConfigurationClassParser processes the @PropertySource annotation and calls addLast to add the resulting property source. As a result, the property source created via @PropertySource has lower precedence than defaultProperties.