Browse Source

Tweak external config file loading to support additional profiles

Profiles set with Environment.setActiveProfiles() (rather than
spring.profiles.active) *before* any config files are processed, are
treated as "additional" (to the ones supplied in spring.profiles.active
from all sources, files and System properties included).

Fixes gh-429
pull/450/head
Dave Syer 12 years ago
parent
commit
aebf3c2bef
  1. 27
      spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java
  2. 32
      spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java
  3. 1
      spring-boot/src/test/resources/application-other.properties
  4. 3
      spring-boot/src/test/resources/enableother.properties
  5. 1
      spring-boot/src/test/resources/enableprofile-other.properties

27
spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java

@ -191,7 +191,10 @@ public class ConfigFileApplicationListener implements
} }
/** /**
* Set the search locations that will be considered as a comma-separated list. * Set the search locations that will be considered as a comma-separated list. Each
* search location should be a directory path (ending in "/") and it will be prefixed
* by the file names constructed from {@link #setSearchNames(String) search names} and
* profiles (if any) plus file extensions supported by the properties loaders.
* Locations are considered in the order specified, with earlier items taking * Locations are considered in the order specified, with earlier items taking
* precedence. * precedence.
*/ */
@ -269,10 +272,18 @@ public class ConfigFileApplicationListener implements
this.profiles = Collections.asLifoQueue(new LinkedList<String>()); this.profiles = Collections.asLifoQueue(new LinkedList<String>());
this.activatedProfiles = false; this.activatedProfiles = false;
// Any pre-existing active profiles take precedence over those added in if (this.environment.containsProperty(ACTIVE_PROFILES_PROPERTY)) {
// config files (unless latter are prefixed with "+"). // Any pre-existing active profiles set via property sources (e.g. System
addActiveProfiles(StringUtils.arrayToCommaDelimitedString(this.environment // properties) take precedence over those added in config files (unless
.getActiveProfiles())); // latter are prefixed with "+").
addActiveProfiles(this.environment.getProperty(ACTIVE_PROFILES_PROPERTY));
}
else {
// Pre-existing active profiles set via Environment.setActiveProfiles()
// are additional profiles and config files are allowed to add more if
// they want to, so don't call addActiveProfiles() here.
this.profiles.addAll(Arrays.asList(this.environment.getActiveProfiles()));
}
this.profiles.add(null); this.profiles.add(null);
@ -336,7 +347,11 @@ public class ConfigFileApplicationListener implements
profile = (addition ? profile.substring(1) : profile); profile = (addition ? profile.substring(1) : profile);
if (profilesNotActivatedWhenCalled || addition) { if (profilesNotActivatedWhenCalled || addition) {
this.profiles.add(profile); this.profiles.add(profile);
prependProfile(this.environment, profile); if (!this.environment.acceptsProfiles(profile)) {
// If it's already accepted we assume the order was set
// intentionally
prependProfile(this.environment, profile);
}
this.activatedProfiles = true; this.activatedProfiles = true;
} }
} }

32
spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java

@ -46,6 +46,7 @@ import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.SimpleCommandLinePropertySource; import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.core.env.StandardEnvironment; import org.springframework.core.env.StandardEnvironment;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@ -97,6 +98,18 @@ public class ConfigFileApplicationListenerTests {
assertThat(property, equalTo("frompropertiesfile")); assertThat(property, equalTo("frompropertiesfile"));
} }
@Test
public void loadTwoPropertiesFilesWithProfiles() throws Exception {
EnvironmentTestUtils.addEnvironment(this.environment, "spring.config.location:"
+ "classpath:enableprofile.properties,"
+ "classpath:enableother.properties");
this.initializer.onApplicationEvent(this.event);
assertEquals("other", StringUtils.arrayToCommaDelimitedString(this.environment
.getActiveProfiles()));
String property = this.environment.getProperty("my.property");
assertThat(property, equalTo("fromotherpropertiesfile"));
}
@Test @Test
public void localFileTakesPrecedenceOverClasspath() throws Exception { public void localFileTakesPrecedenceOverClasspath() throws Exception {
File localFile = new File(new File("."), "application.properties"); File localFile = new File(new File("."), "application.properties");
@ -180,6 +193,25 @@ public class ConfigFileApplicationListenerTests {
this.initializer.setSearchNames("enableprofile"); this.initializer.setSearchNames("enableprofile");
this.initializer.onApplicationEvent(this.event); this.initializer.onApplicationEvent(this.event);
String property = this.environment.getProperty("my.property"); String property = this.environment.getProperty("my.property");
// The "myprofile" profile is activated in enableprofile.properties so its value
// should show up here
assertThat(property, equalTo("fromprofilepropertiesfile"));
}
@Test
public void loadPropertiesThenProfilePropertiesWithOverride() throws Exception {
this.environment.setActiveProfiles("other");
// EnvironmentTestUtils.addEnvironment(this.environment,
// "spring.profiles.active:other");
this.initializer.setSearchNames("enableprofile");
this.initializer.onApplicationEvent(this.event);
String property = this.environment.getProperty("other.property");
// The "other" profile is activated before any processing starts
assertThat(property, equalTo("fromotherpropertiesfile"));
property = this.environment.getProperty("my.property");
// The "myprofile" profile is activated in enableprofile.properties and "other"
// was not activated by setting spring.profiles.active so "myprofile" should still
// be activated
assertThat(property, equalTo("fromprofilepropertiesfile")); assertThat(property, equalTo("fromprofilepropertiesfile"));
} }

1
spring-boot/src/test/resources/application-other.properties

@ -0,0 +1 @@
my.property=fromotherpropertiesfile

3
spring-boot/src/test/resources/enableother.properties

@ -0,0 +1,3 @@
spring.profiles.active=other
my.property=fromenableotherpropertiesfile
one.more=${my.property}

1
spring-boot/src/test/resources/enableprofile-other.properties

@ -0,0 +1 @@
other.property=fromotherpropertiesfile
Loading…
Cancel
Save