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 92584ec1d37..62a61f77d45 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 @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.Deque; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; @@ -656,27 +657,35 @@ public class ConfigFileApplicationListener private void addLoadedPropertySources() { MutablePropertySources destination = this.environment.getPropertySources(); - String lastAdded = null; List loaded = new ArrayList<>(this.loaded.values()); Collections.reverse(loaded); + String lastAdded = null; + Set added = new HashSet<>(); for (MutablePropertySources sources : loaded) { for (PropertySource source : sources) { - if (lastAdded == null) { - if (destination.contains(DEFAULT_PROPERTIES)) { - destination.addBefore(DEFAULT_PROPERTIES, source); - } - else { - destination.addLast(source); - } + if (added.add(source.getName())) { + addLoadedPropertySource(destination, lastAdded, source); + lastAdded = source.getName(); } - else { - destination.addAfter(lastAdded, source); - } - lastAdded = source.getName(); } } } + private void addLoadedPropertySource(MutablePropertySources destination, + String lastAdded, PropertySource source) { + if (lastAdded == null) { + if (destination.contains(DEFAULT_PROPERTIES)) { + destination.addBefore(DEFAULT_PROPERTIES, source); + } + else { + destination.addLast(source); + } + } + else { + destination.addAfter(lastAdded, source); + } + } + } /** 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 e0be4d14625..1d82d42e113 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 @@ -900,7 +900,18 @@ public class ConfigFileApplicationListenerTests { this.context = application.run("--spring.config.name=applicationloop"); ConfigurableEnvironment environment = this.context.getEnvironment(); assertThat(environment.acceptsProfiles("loop")).isTrue(); + } + @Test + public void multiValueSpringProfiles() { + // gh-13362 + SpringApplication application = new SpringApplication(Config.class); + application.setWebApplicationType(WebApplicationType.NONE); + this.context = application.run("--spring.config.name=applicationmultiprofiles"); + ConfigurableEnvironment environment = this.context.getEnvironment(); + assertThat(environment.acceptsProfiles("test")).isTrue(); + assertThat(environment.acceptsProfiles("another-test")).isTrue(); + assertThat(environment.getProperty("message")).isEqualTo("multiprofile"); } private Condition matchingPropertySource( diff --git a/spring-boot-project/spring-boot/src/test/resources/applicationmultiprofiles.yml b/spring-boot-project/spring-boot/src/test/resources/applicationmultiprofiles.yml new file mode 100644 index 00000000000..bf406504019 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/applicationmultiprofiles.yml @@ -0,0 +1,6 @@ +spring.profiles.active: test, another-test +message: default +--- +spring: + profiles: test,another-test +message: multiprofile