Allow multi-value spring.profiles properties

Update `ConfigFileApplicationListener` to correctly load properties
that have `spring.profiles` values containing a list.

Prior to this commit the loaded would attempt to add the same document
twice resulting in a "property source cannot be added relative to
itself" error.

Closes gh-13362
pull/13388/head
Phillip Webb 7 years ago
parent 67b548dafb
commit e1d21e52d5

@ -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,11 +657,22 @@ public class ConfigFileApplicationListener
private void addLoadedPropertySources() {
MutablePropertySources destination = this.environment.getPropertySources();
String lastAdded = null;
List<MutablePropertySources> loaded = new ArrayList<>(this.loaded.values());
Collections.reverse(loaded);
String lastAdded = null;
Set<String> added = new HashSet<>();
for (MutablePropertySources sources : loaded) {
for (PropertySource<?> source : sources) {
if (added.add(source.getName())) {
addLoadedPropertySource(destination, 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);
@ -672,9 +684,6 @@ public class ConfigFileApplicationListener
else {
destination.addAfter(lastAdded, source);
}
lastAdded = source.getName();
}
}
}
}

@ -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<ConfigurableEnvironment> matchingPropertySource(

@ -0,0 +1,6 @@
spring.profiles.active: test, another-test
message: default
---
spring:
profiles: test,another-test
message: multiprofile
Loading…
Cancel
Save