Commit 8528f7c1 authored by Madhura Bhave's avatar Madhura Bhave

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
parent 99656b9d
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment