diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java index db673909cd..8a47727dd3 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java @@ -337,6 +337,7 @@ public class ConfigFileApplicationListener addToLoaded(MutablePropertySources::addLast, false)); this.processedProfiles.add(profile); } + resetEnvironmentProfiles(this.processedProfiles); load(null, this::getNegativeProfileFilter, addToLoaded(MutablePropertySources::addFirst, true)); addLoadedPropertySources(); @@ -673,6 +674,21 @@ public class ConfigFileApplicationListener return new LinkedHashSet<>(list); } + /** + * This ensures that the order of active profiles in the {@link Environment} + * matches the order in which the profiles were processed. + * @param processedProfiles the processed profiles + */ + private void resetEnvironmentProfiles(List processedProfiles) { + String[] names = processedProfiles.stream().filter((profile) -> { + if (profile != null && !profile.isDefaultProfile()) { + return true; + } + return false; + }).map(Profile::getName).toArray(String[]::new); + this.environment.setActiveProfiles(names); + } + private void addLoadedPropertySources() { MutablePropertySources destination = this.environment.getPropertySources(); List loaded = new ArrayList<>(this.loaded.values()); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java index 228782a427..a306113928 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java @@ -406,7 +406,7 @@ public class ConfigFileApplicationListenerTests { TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, "spring.profiles.active=dev", "spring.profiles.include=other"); this.initializer.postProcessEnvironment(this.environment, this.application); - assertThat(this.environment.getActiveProfiles()).contains("dev", "other"); + assertThat(this.environment.getActiveProfiles()).containsExactly("other", "dev"); assertThat(this.environment.getProperty("my.property")) .isEqualTo("fromdevpropertiesfile"); validateProfilePrecedence(null, "other", "dev"); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerYamlProfileNegationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerYamlProfileNegationTests.java index 74d1cdb676..c266ac3f15 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerYamlProfileNegationTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerYamlProfileNegationTests.java @@ -116,6 +116,20 @@ public class ConfigFileApplicationListenerYamlProfileNegationTests { assertThat(this.context.getEnvironment().getProperty("not-e")).isNull(); } + @Test + public void yamlProfileCascadingMultipleActiveProfilesViaPropertiesShouldPreserveOrder() { + SpringApplication application = new SpringApplication(Config.class); + application.setWebApplicationType(WebApplicationType.NONE); + String configName = "--spring.config.name=cascadingprofiles"; + this.context = application.run(configName, "--spring.profiles.active=A,B"); + assertVersionProperty(this.context, "D", "A", "C", "E", "B", "D"); + assertThat(this.context.getEnvironment().getProperty("not-a")).isNull(); + assertThat(this.context.getEnvironment().getProperty("not-b")).isNull(); + assertThat(this.context.getEnvironment().getProperty("not-c")).isNull(); + assertThat(this.context.getEnvironment().getProperty("not-d")).isNull(); + assertThat(this.context.getEnvironment().getProperty("not-e")).isNull(); + } + @Test public void yamlProfileCascadingOverrideProfilesB() { SpringApplication application = new SpringApplication(Config.class);