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

@ -412,6 +412,16 @@ public class ConfigFileApplicationListenerTests {
validateProfilePrecedence(null, "other", "dev"); 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 @Test
public void profilesAddedToEnvironmentAndViaPropertyDuplicate() { public void profilesAddedToEnvironmentAndViaPropertyDuplicate() {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,

Loading…
Cancel
Save