diff --git a/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java b/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java index e8389745f6a..cf56bb4ce43 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java @@ -47,6 +47,7 @@ import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.ConfigurationClassPostProcessor; import org.springframework.core.Ordered; +import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.env.ConfigurableEnvironment; @@ -153,16 +154,20 @@ public class ConfigFileApplicationListener implements EnvironmentPostProcessor, private void onApplicationEnvironmentPreparedEvent( ApplicationEnvironmentPreparedEvent event) { - List postProcessors = SpringFactoriesLoader - .loadFactories(EnvironmentPostProcessor.class, - getClass().getClassLoader()); + List postProcessors = loadPostProcessors(); postProcessors.add(this); + AnnotationAwareOrderComparator.sort(postProcessors); for (EnvironmentPostProcessor postProcessor : postProcessors) { postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication()); } } + List loadPostProcessors() { + return SpringFactoriesLoader.loadFactories(EnvironmentPostProcessor.class, + getClass().getClassLoader()); + } + @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { diff --git a/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java b/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java index d15c8d558c8..97a49e60051 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java @@ -44,8 +44,10 @@ import org.springframework.beans.CachedIntrospectionResults; import org.springframework.boot.Banner; import org.springframework.boot.SpringApplication; import org.springframework.boot.context.config.ConfigFileApplicationListener.ConfigurationPropertySources; +import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; import org.springframework.boot.context.event.ApplicationPreparedEvent; import org.springframework.boot.env.EnumerableCompositePropertySource; +import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.boot.test.OutputCapture; import org.springframework.context.ConfigurableApplicationContext; @@ -53,6 +55,8 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MutablePropertySources; @@ -67,6 +71,7 @@ import org.springframework.util.StringUtils; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; @@ -445,6 +450,13 @@ public class ConfigFileApplicationListenerTests { validateProfilePrecedence(null, "other", "dev"); } + @Test + public void postProcessorsAreOrderedCorrectly() { + TestConfigFileApplicationListener testListener = new TestConfigFileApplicationListener(); + testListener.onApplicationEvent(new ApplicationEnvironmentPreparedEvent( + this.application, new String[0], this.environment)); + } + private void validateProfilePrecedence(String... profiles) { ApplicationPreparedEvent event = new ApplicationPreparedEvent( new SpringApplication(), new String[0], @@ -868,4 +880,27 @@ public class ConfigFileApplicationListenerTests { } + private static class TestConfigFileApplicationListener + extends ConfigFileApplicationListener { + + @Override + List loadPostProcessors() { + return new ArrayList( + Arrays.asList(new LowestPrecedenceEnvironmentPostProcessor())); + } + + } + + @Order(Ordered.LOWEST_PRECEDENCE) + private static class LowestPrecedenceEnvironmentPostProcessor + implements EnvironmentPostProcessor { + + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, + SpringApplication application) { + assertThat(environment.getPropertySources().size(), is(equalTo(4))); + } + + } + }