Commit 2118242e authored by Phillip Webb's avatar Phillip Webb

Polish

parent 8c140092
...@@ -374,6 +374,7 @@ specified by the `spring.active.profiles` property are added after those configu ...@@ -374,6 +374,7 @@ specified by the `spring.active.profiles` property are added after those configu
the `SpringApplication` API and therefore take precedence. the `SpringApplication` API and therefore take precedence.
[[boot-features-external-config-placeholders-in-properties]] [[boot-features-external-config-placeholders-in-properties]]
=== Placeholders in properties === Placeholders in properties
The values in `application.properties` are filtered through the existing `Environment` The values in `application.properties` are filtered through the existing `Environment`
......
...@@ -307,25 +307,14 @@ public class ConfigFileApplicationListener ...@@ -307,25 +307,14 @@ public class ConfigFileApplicationListener
public void load() throws IOException { public void load() throws IOException {
this.propertiesLoader = new PropertySourcesLoader(); this.propertiesLoader = new PropertySourcesLoader();
this.profiles = Collections.asLifoQueue(new LinkedList<String>());
this.activatedProfiles = false; this.activatedProfiles = false;
this.profiles = Collections.asLifoQueue(new LinkedList<String>());
Set<String> initialActiveProfiles = null;
if (this.environment.containsProperty(ACTIVE_PROFILES_PROPERTY)) {
// Any pre-existing active profiles set via property sources (e.g. System
// properties) take precedence over those added in config files.
initialActiveProfiles = maybeActivateProfiles(
this.environment.getProperty(ACTIVE_PROFILES_PROPERTY));
}
// Pre-existing active profiles set via Environment.setActiveProfiles() // Pre-existing active profiles set via Environment.setActiveProfiles()
// are additional profiles and config files are allowed to add more if // are additional profiles and config files are allowed to add more if
// they want to, so don't call addActiveProfiles() here. // they want to, so don't call addActiveProfiles() here.
List<String> list = filterEnvironmentProfiles(initialActiveProfiles != null Set<String> initialActiveProfiles = initializeActiveProfiles();
? initialActiveProfiles : Collections.<String>emptySet()); this.profiles.addAll(getUnprocessedActiveProfiles(initialActiveProfiles));
// Reverse them so the order is the same as from getProfilesForValue()
// (last one wins when properties are eventually resolved)
Collections.reverse(list);
this.profiles.addAll(list);
// 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
// last so that it is first out of the queue (active profiles will then // last so that it is first out of the queue (active profiles will then
...@@ -351,6 +340,44 @@ public class ConfigFileApplicationListener ...@@ -351,6 +340,44 @@ public class ConfigFileApplicationListener
addConfigurationProperties(this.propertiesLoader.getPropertySources()); addConfigurationProperties(this.propertiesLoader.getPropertySources());
} }
private Set<String> initializeActiveProfiles() {
if (!this.environment.containsProperty(ACTIVE_PROFILES_PROPERTY)) {
return Collections.emptySet();
}
// Any pre-existing active profiles set via property sources (e.g. System
// properties) take precedence over those added in config files.
Set<String> activeProfiles = getProfilesForValue(
this.environment.getProperty(ACTIVE_PROFILES_PROPERTY));
maybeActivateProfiles(activeProfiles);
return activeProfiles;
}
/**
* Return the active profiles that have not been processed yet. If a profile is
* enabled via both {@link #ACTIVE_PROFILES_PROPERTY} and
* {@link ConfigurableEnvironment#addActiveProfile(String)} it needs to be
* filtered so that the {@link #ACTIVE_PROFILES_PROPERTY} value takes precedence.
* <p>
* Concretely, if the "cloud" profile is enabled via the environment, it will take
* less precedence that any profile set via the {@link #ACTIVE_PROFILES_PROPERTY}.
* @param initialActiveProfiles the profiles that have been enabled via
* {@link #ACTIVE_PROFILES_PROPERTY}
* @return the unprocessed active profiles from the environment to enable
*/
private List<String> getUnprocessedActiveProfiles(
Set<String> initialActiveProfiles) {
List<String> unprocessedActiveProfiles = new ArrayList<String>();
for (String profile : this.environment.getActiveProfiles()) {
if (!initialActiveProfiles.contains(profile)) {
unprocessedActiveProfiles.add(profile);
}
}
// Reverse them so the order is the same as from getProfilesForValue()
// (last one wins when properties are eventually resolved)
Collections.reverse(unprocessedActiveProfiles);
return unprocessedActiveProfiles;
}
private void load(String location, String name, String profile) private void load(String location, String name, String profile)
throws IOException { throws IOException {
String group = "profile=" + (profile == null ? "" : profile); String group = "profile=" + (profile == null ? "" : profile);
...@@ -387,10 +414,7 @@ public class ConfigFileApplicationListener ...@@ -387,10 +414,7 @@ public class ConfigFileApplicationListener
propertySource = this.propertiesLoader.load(resource, group, name, propertySource = this.propertiesLoader.load(resource, group, name,
profile); profile);
if (propertySource != null) { if (propertySource != null) {
maybeActivateProfiles( handleProfileProperties(propertySource);
propertySource.getProperty(ACTIVE_PROFILES_PROPERTY));
addIncludeProfiles(
propertySource.getProperty(INCLUDE_PROFILES_PROPERTY));
} }
} }
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
...@@ -407,58 +431,37 @@ public class ConfigFileApplicationListener ...@@ -407,58 +431,37 @@ public class ConfigFileApplicationListener
return propertySource; return propertySource;
} }
/** private void handleProfileProperties(PropertySource<?> propertySource) {
* Return the active profiles that have not been processed yet. Set<String> activeProfiles = getProfilesForValue(
* <p>If a profile is enabled via both {@link #ACTIVE_PROFILES_PROPERTY} and propertySource.getProperty(ACTIVE_PROFILES_PROPERTY));
* {@link ConfigurableEnvironment#addActiveProfile(String)} it needs to be maybeActivateProfiles(activeProfiles);
* filtered so that the {@link #ACTIVE_PROFILES_PROPERTY} value takes Set<String> includeProfiles = getProfilesForValue(
* precedence. propertySource.getProperty(INCLUDE_PROFILES_PROPERTY));
* <p>Concretely, if the "cloud" profile is enabled via the environment, addProfiles(includeProfiles);
* it will take less precedence that any profile set via the
* {@link #ACTIVE_PROFILES_PROPERTY}.
* @param initialActiveProfiles the profiles that have been enabled via
* {@link #ACTIVE_PROFILES_PROPERTY}
* @return the additional profiles from the environment to enable
*/
private List<String> filterEnvironmentProfiles(Set<String> initialActiveProfiles) {
List<String> additionalProfiles = new ArrayList<String>();
for (String profile : this.environment.getActiveProfiles()) {
if (!initialActiveProfiles.contains(profile)) {
additionalProfiles.add(profile);
}
}
return additionalProfiles;
} }
private Set<String> maybeActivateProfiles(Object value) { private void maybeActivateProfiles(Set<String> profiles) {
if (this.activatedProfiles) { if (this.activatedProfiles) {
if (value != null) { if (!profiles.isEmpty()) {
this.debug.add("Profiles already activated, '" + value this.debug.add("Profiles already activated, '" + profiles
+ "' will not be applied"); + "' will not be applied");
} }
return Collections.emptySet(); return;
} }
Set<String> profiles = getProfilesForValue(value);
activateProfiles(profiles);
if (profiles.size() > 0) { if (profiles.size() > 0) {
addProfiles(profiles);
this.debug.add("Activated profiles " this.debug.add("Activated profiles "
+ StringUtils.collectionToCommaDelimitedString(profiles)); + StringUtils.collectionToCommaDelimitedString(profiles));
this.activatedProfiles = true; this.activatedProfiles = true;
} }
return profiles;
}
private void addIncludeProfiles(Object value) {
Set<String> profiles = getProfilesForValue(value);
activateProfiles(profiles);
} }
private Set<String> getProfilesForValue(Object property) { private Set<String> getProfilesForValue(Object property) {
return asResolvedSet((property == null ? null : property.toString()), null); String value = (property == null ? null : property.toString());
return asResolvedSet(value, null);
} }
private void activateProfiles(Set<String> profiles) { private void addProfiles(Set<String> profiles) {
for (String profile : profiles) { for (String profile : profiles) {
this.profiles.add(profile); this.profiles.add(profile);
if (!this.environment.acceptsProfiles(profile)) { if (!this.environment.acceptsProfiles(profile)) {
......
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