Make spring.profiles.include behave consistently

Previously, if profiles were included via a property source with higher
precedence than config files, profiles activated via config files would
not be taken into account. This commit makes spring.profiles.include
behave consistently where it adds to active profiles rather than replacing
them, regardless of property source.

Fixes gh-15344
pull/15883/head
Madhura Bhave 6 years ago
parent 99656b9dd8
commit 8528f7c140

@ -348,10 +348,16 @@ public class ConfigFileApplicationListener
// The default profile for these purposes is represented as null. We add it
// first so that it is processed first and has lowest priority.
this.profiles.add(null);
Set<Profile> activatedViaProperty = getProfilesActivatedViaProperty();
this.profiles.addAll(getOtherActiveProfiles(activatedViaProperty));
Set<Profile> activatedViaProperty = getProfilesFromProperty(
ACTIVE_PROFILES_PROPERTY);
Set<Profile> includedViaProperty = getProfilesFromProperty(
INCLUDE_PROFILES_PROPERTY);
List<Profile> otherActiveProfiles = getOtherActiveProfiles(
activatedViaProperty, includedViaProperty);
this.profiles.addAll(otherActiveProfiles);
// Any pre-existing active profiles set via property sources (e.g.
// System properties) take precedence over those added in config files.
this.profiles.addAll(includedViaProperty);
addActiveProfiles(activatedViaProperty);
if (this.profiles.size() == 1) { // only has null profile
for (String defaultProfileName : this.environment.getDefaultProfiles()) {
@ -361,21 +367,20 @@ public class ConfigFileApplicationListener
}
}
private Set<Profile> getProfilesActivatedViaProperty() {
if (!this.environment.containsProperty(ACTIVE_PROFILES_PROPERTY)
&& !this.environment.containsProperty(INCLUDE_PROFILES_PROPERTY)) {
private Set<Profile> getProfilesFromProperty(String profilesProperty) {
if (!this.environment.containsProperty(profilesProperty)) {
return Collections.emptySet();
}
Binder binder = Binder.get(this.environment);
Set<Profile> activeProfiles = new LinkedHashSet<>();
activeProfiles.addAll(getProfiles(binder, INCLUDE_PROFILES_PROPERTY));
activeProfiles.addAll(getProfiles(binder, ACTIVE_PROFILES_PROPERTY));
return activeProfiles;
Set<Profile> profiles = getProfiles(binder, profilesProperty);
return new LinkedHashSet<>(profiles);
}
private List<Profile> getOtherActiveProfiles(Set<Profile> activatedViaProperty) {
private List<Profile> getOtherActiveProfiles(Set<Profile> activatedViaProperty,
Set<Profile> includedViaProperty) {
return Arrays.stream(this.environment.getActiveProfiles()).map(Profile::new)
.filter((profile) -> !activatedViaProperty.contains(profile))
.filter((profile) -> !activatedViaProperty.contains(profile)
&& !includedViaProperty.contains(profile))
.collect(Collectors.toList());
}

@ -412,6 +412,16 @@ public class ConfigFileApplicationListenerTests {
validateProfilePrecedence(null, "other", "dev");
}
@Test
public void profilesAddedViaIncludePropertyAndActivatedViaAnotherPropertySource() {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
"spring.profiles.include=dev,simple");
this.initializer.postProcessEnvironment(this.environment, this.application);
assertThat(this.environment.getActiveProfiles()).containsExactly("dev", "simple",
"other");
validateProfilePrecedence("dev", "simple", "other");
}
@Test
public void profilesAddedToEnvironmentAndViaPropertyDuplicate() {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,

Loading…
Cancel
Save