Skip to content

Commit 44c979b

Browse files
committed
Reorder default property sources after @propertysource processing
Update `SpringApplication` so that the `DefaultPropertiesPropertySource` is moved to the end after `@PropertySource` annotations have been processed. This restores functionality that used to be handled by the `ConfigFileApplicationListener` and was inadvertently dropped when the `ConfigDataEnvironmentPostProcessor` was developed. Fixes gh-31068
1 parent 350d27f commit 44c979b

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@
3333
import org.apache.commons.logging.LogFactory;
3434

3535
import org.springframework.beans.BeanUtils;
36+
import org.springframework.beans.BeansException;
3637
import org.springframework.beans.CachedIntrospectionResults;
3738
import org.springframework.beans.factory.config.BeanDefinition;
39+
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
3840
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
3941
import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
4042
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
@@ -56,9 +58,11 @@
5658
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
5759
import org.springframework.context.annotation.AnnotationConfigUtils;
5860
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
61+
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
5962
import org.springframework.context.support.AbstractApplicationContext;
6063
import org.springframework.context.support.GenericApplicationContext;
6164
import org.springframework.core.GenericTypeResolver;
65+
import org.springframework.core.Ordered;
6266
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
6367
import org.springframework.core.env.CommandLinePropertySource;
6468
import org.springframework.core.env.CompositePropertySource;
@@ -434,6 +438,7 @@ private void prepareContext(DefaultBootstrapContext bootstrapContext, Configurab
434438
if (this.lazyInitialization) {
435439
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
436440
}
441+
context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
437442
// Load the sources
438443
Set<Object> sources = getAllSources();
439444
Assert.notEmpty(sources, "Sources must not be empty");
@@ -1430,4 +1435,28 @@ private static <E> Set<E> asUnmodifiableOrderedSet(Collection<E> elements) {
14301435
return new LinkedHashSet<>(list);
14311436
}
14321437

1438+
/**
1439+
* {@link BeanFactoryPostProcessor} to re-order our property sources below any
1440+
* {@code @PropertySource} items added by the {@link ConfigurationClassPostProcessor}.
1441+
*/
1442+
private static class PropertySourceOrderingBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
1443+
1444+
private final ConfigurableApplicationContext context;
1445+
1446+
PropertySourceOrderingBeanFactoryPostProcessor(ConfigurableApplicationContext context) {
1447+
this.context = context;
1448+
}
1449+
1450+
@Override
1451+
public int getOrder() {
1452+
return Ordered.HIGHEST_PRECEDENCE;
1453+
}
1454+
1455+
@Override
1456+
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
1457+
DefaultPropertiesPropertySource.moveToEnd(this.context.getEnvironment());
1458+
}
1459+
1460+
}
1461+
14331462
}

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,16 @@ void bindsEnvironmentPrefixToSpringApplication() {
13091309
assertThat(application.getEnvironmentPrefix()).isEqualTo("my");
13101310
}
13111311

1312+
@Test
1313+
void movesConfigClassPropertySourcesToEnd() {
1314+
SpringApplication application = new SpringApplication(PropertySourceConfig.class);
1315+
application.setWebApplicationType(WebApplicationType.NONE);
1316+
application.setDefaultProperties(Collections.singletonMap("test.name", "test"));
1317+
this.context = application.run();
1318+
assertThat(this.context.getEnvironment().getProperty("test.name"))
1319+
.isEqualTo("spring-application-config-property-source");
1320+
}
1321+
13121322
@Test
13131323
void deregistersShutdownHookForFailedApplicationContext() {
13141324
SpringApplication application = new SpringApplication(BrokenPostConstructConfig.class);
@@ -1667,6 +1677,12 @@ static class NotLazyBean {
16671677

16681678
}
16691679

1680+
@Configuration(proxyBeanMethods = false)
1681+
@org.springframework.context.annotation.PropertySource("classpath:spring-application-config-property-source.properties")
1682+
static class PropertySourceConfig {
1683+
1684+
}
1685+
16701686
static class ExitStatusException extends RuntimeException implements ExitCodeGenerator {
16711687

16721688
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test.name=spring-application-config-property-source

0 commit comments

Comments
 (0)