Load configuration from default profiles if no others active

Before this change if no profile is active yaml documents with
spring.profiles=default were loaded, but they are also loaded
if there *is* an active profile which is more of a problem. In
addition if the user chanes the default profile in the
Environmemt Spring Boot ignore that value ("default" is a magic
String).

After this change:

* If no profile is explicitly active, the default profiles from
the Environment are used explicitly
* The default profiles cause properties to be loaded just like
other profiles, so from YAML documents with spring.profiles and
from files in application-default.properties for instance
* The default profiles are not active when any other profile is
* Properties defined in "top-level" YAML documents with no
specific spring.profiles still act as defaults for *all* profiles

Fixes gh-1219, fixes gh-2623
This commit is contained in:
Dave Syer
2015-07-03 15:06:49 +01:00
parent dfbabefcd2
commit dc8ba2c535
7 changed files with 80 additions and 2 deletions

View File

@@ -322,6 +322,14 @@ public class ConfigFileApplicationListener implements
this.profiles.addAll(list);
}
if (this.profiles.isEmpty()) {
for (String defaultProfile : this.environment.getDefaultProfiles()) {
if (!this.profiles.contains(defaultProfile)) {
this.profiles.add(defaultProfile);
}
}
}
// 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
// override any settings in the defaults when the list is reversed later).
@@ -376,7 +384,7 @@ public class ConfigFileApplicationListener implements
String profile) throws IOException {
Resource resource = this.resourceLoader.getResource(location);
PropertySource<?> propertySource = null;
if (resource != null) {
if (resource != null && resource.exists()) {
String name = "applicationConfig: [" + location + "]";
String group = "applicationConfig: [" + identifier + "]";
propertySource = this.propertiesLoader.load(resource, group, name,

View File

@@ -16,6 +16,7 @@
package org.springframework.boot.yaml;
import java.util.Collections;
import java.util.Properties;
import java.util.Set;
@@ -49,6 +50,9 @@ public class ArrayDocumentMatcher implements DocumentMatcher {
}
Set<String> values = StringUtils.commaDelimitedListToSet(properties
.getProperty(this.key));
if (values.isEmpty()) {
values = Collections.singleton("");
}
for (String pattern : this.patterns) {
for (String value : values) {
if (value.matches(pattern)) {

View File

@@ -34,7 +34,7 @@ import org.springframework.core.env.Environment;
*/
public class SpringProfileDocumentMatcher implements DocumentMatcher {
private static final String[] DEFAULT_PROFILES = new String[] { "default" };
private static final String[] DEFAULT_PROFILES = new String[] { "^\\s*$" };
private String[] activeProfiles = new String[0];

View File

@@ -123,6 +123,15 @@ public class ConfigFileApplicationListenerTests {
assertThat(property, equalTo("frompropertiesfile"));
}
@Test
public void loadDefaultPropertiesFile() throws Exception {
this.environment.setDefaultProfiles("thedefault");
this.initializer.setSearchNames("testprofiles");
this.initializer.onApplicationEvent(this.event);
String property = this.environment.getProperty("the.property");
assertThat(property, equalTo("fromdefaultpropertiesfile"));
}
@Test
public void loadTwoPropertiesFile() throws Exception {
EnvironmentTestUtils.addEnvironment(this.environment, "spring.config.location:"
@@ -243,6 +252,33 @@ public class ConfigFileApplicationListenerTests {
assertThat(this.environment.getProperty("my.array"), nullValue(String.class));
}
@Test
public void loadProfileEmptySameAsNotSpecified() throws Exception {
this.initializer.setSearchNames("testprofilesempty");
this.initializer.onApplicationEvent(this.event);
String property = this.environment.getProperty("my.property");
assertThat(property, equalTo("fromemptyprofile"));
}
@Test
public void loadDefaultYamlDocument() throws Exception {
this.environment.setDefaultProfiles("thedefault");
this.initializer.setSearchNames("testprofilesdocument");
this.initializer.onApplicationEvent(this.event);
String property = this.environment.getProperty("my.property");
assertThat(property, equalTo("fromdefaultprofile"));
}
@Test
public void loadDefaultYamlDocumentNotActivated() throws Exception {
this.environment.setDefaultProfiles("thedefault");
this.environment.setActiveProfiles("other");
this.initializer.setSearchNames("testprofilesdocument");
this.initializer.onApplicationEvent(this.event);
String property = this.environment.getProperty("my.property");
assertThat(property, equalTo("fromotherprofile"));
}
@Test
public void commandLineWins() throws Exception {
this.environment.getPropertySources().addFirst(

View File

@@ -0,0 +1,2 @@
my.property=fromdefaultpropertiesfile
the.property=fromdefaultpropertiesfile

View File

@@ -0,0 +1,14 @@
---
my:
property: fromyamlfile
other: notempty
---
spring:
profiles: thedefault
my:
property: fromdefaultprofile
---
spring:
profiles: other
my:
property: fromotherprofile

View File

@@ -0,0 +1,14 @@
---
my:
property: fromyamlfile
other: notempty
---
spring:
profiles:
my:
property: fromemptyprofile
---
spring:
profiles: other
my:
property: fromotherprofile