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
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
spring.profiles.active=other
|
||||
Reference in New Issue
Block a user