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.