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
This commit is contained in:
parent
350d27fe50
commit
44c979beb0
|
@ -33,8 +33,10 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.CachedIntrospectionResults;
|
import org.springframework.beans.CachedIntrospectionResults;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
|
import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
@ -56,9 +58,11 @@ import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.AnnotationConfigUtils;
|
import org.springframework.context.annotation.AnnotationConfigUtils;
|
||||||
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
||||||
|
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
|
||||||
import org.springframework.context.support.AbstractApplicationContext;
|
import org.springframework.context.support.AbstractApplicationContext;
|
||||||
import org.springframework.context.support.GenericApplicationContext;
|
import org.springframework.context.support.GenericApplicationContext;
|
||||||
import org.springframework.core.GenericTypeResolver;
|
import org.springframework.core.GenericTypeResolver;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||||
import org.springframework.core.env.CommandLinePropertySource;
|
import org.springframework.core.env.CommandLinePropertySource;
|
||||||
import org.springframework.core.env.CompositePropertySource;
|
import org.springframework.core.env.CompositePropertySource;
|
||||||
|
@ -434,6 +438,7 @@ public class SpringApplication {
|
||||||
if (this.lazyInitialization) {
|
if (this.lazyInitialization) {
|
||||||
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
|
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
|
||||||
}
|
}
|
||||||
|
context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
|
||||||
// Load the sources
|
// Load the sources
|
||||||
Set<Object> sources = getAllSources();
|
Set<Object> sources = getAllSources();
|
||||||
Assert.notEmpty(sources, "Sources must not be empty");
|
Assert.notEmpty(sources, "Sources must not be empty");
|
||||||
|
@ -1430,4 +1435,28 @@ public class SpringApplication {
|
||||||
return new LinkedHashSet<>(list);
|
return new LinkedHashSet<>(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link BeanFactoryPostProcessor} to re-order our property sources below any
|
||||||
|
* {@code @PropertySource} items added by the {@link ConfigurationClassPostProcessor}.
|
||||||
|
*/
|
||||||
|
private static class PropertySourceOrderingBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
|
||||||
|
|
||||||
|
private final ConfigurableApplicationContext context;
|
||||||
|
|
||||||
|
PropertySourceOrderingBeanFactoryPostProcessor(ConfigurableApplicationContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return Ordered.HIGHEST_PRECEDENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||||
|
DefaultPropertiesPropertySource.moveToEnd(this.context.getEnvironment());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1309,6 +1309,16 @@ class SpringApplicationTests {
|
||||||
assertThat(application.getEnvironmentPrefix()).isEqualTo("my");
|
assertThat(application.getEnvironmentPrefix()).isEqualTo("my");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void movesConfigClassPropertySourcesToEnd() {
|
||||||
|
SpringApplication application = new SpringApplication(PropertySourceConfig.class);
|
||||||
|
application.setWebApplicationType(WebApplicationType.NONE);
|
||||||
|
application.setDefaultProperties(Collections.singletonMap("test.name", "test"));
|
||||||
|
this.context = application.run();
|
||||||
|
assertThat(this.context.getEnvironment().getProperty("test.name"))
|
||||||
|
.isEqualTo("spring-application-config-property-source");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void deregistersShutdownHookForFailedApplicationContext() {
|
void deregistersShutdownHookForFailedApplicationContext() {
|
||||||
SpringApplication application = new SpringApplication(BrokenPostConstructConfig.class);
|
SpringApplication application = new SpringApplication(BrokenPostConstructConfig.class);
|
||||||
|
@ -1667,6 +1677,12 @@ class SpringApplicationTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@org.springframework.context.annotation.PropertySource("classpath:spring-application-config-property-source.properties")
|
||||||
|
static class PropertySourceConfig {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static class ExitStatusException extends RuntimeException implements ExitCodeGenerator {
|
static class ExitStatusException extends RuntimeException implements ExitCodeGenerator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
test.name=spring-application-config-property-source
|
Loading…
Reference in New Issue