Restore active profile logic and support +

Restore the previous `spring.profiles.active` logic effectively
reverting commit 37069d9. This ensures that active profiles defined in
a higher `PropertySource` replace those lower down.

In addition, add support for a `+` prefix that can be used to indicate
that a profile should be added to the active set.

For example:

	# application-prod.properties
	spring.profiles.active=+proddb,+prodmq

Fixed gh-308, gh-309
This commit is contained in:
Phillip Webb 2014-02-04 14:06:02 -08:00
parent 31c385470e
commit 6ddbf3bd92
8 changed files with 58 additions and 17 deletions

View File

@ -894,7 +894,7 @@ In Spring Boot you can also set the active profile in
`application.properties`, e.g. `application.properties`, e.g.
```properties ```properties
spring.profiles.active: production spring.profiles.active=production
``` ```
A value set this way is replaced by the System property or environment A value set this way is replaced by the System property or environment
@ -902,6 +902,7 @@ variable setting, but not by the `SpringApplicationBuilder.profiles()`
method. Thus the latter Java API can be used to augment the profiles method. Thus the latter Java API can be used to augment the profiles
without changing the defaults. without changing the defaults.
## Change the Location of External Properties of an Application ## Change the Location of External Properties of an Application
By default properties from different sources are added to the Spring By default properties from different sources are added to the Spring

View File

@ -157,6 +157,26 @@ spring.profiles.active=dev,hsqldb
or specify on the command line using the switch `--spring.profiles.active=dev,hsqldb`. or specify on the command line using the switch `--spring.profiles.active=dev,hsqldb`.
#### Adding active profiles
The `spring.profiles.active` property follows the same ordering rules as other
properties, the highest `PropertySource` will win. This means that you can specify
active profiles in `application.properties` then **replace** them using the command line
switch.
Sometimes it is useful to have profile specific properties that **add** to the active
profiles rather than replace them. The `+` prefix can be used to add active profiles.
For example, when an application with following properties is run using the switch
`--spring.profiles.active=prod` the `proddb` and `prodmq` profiles will also be activated:
```yaml
---
my.property: fromyamlfile
---
spring.profiles: prod
spring.profiles.active: +proddb,+prodmq
```
### Application Context Initializers ### Application Context Initializers
Spring provides a convenient `ApplicationContextInitializer` interface that can be used Spring provides a convenient `ApplicationContextInitializer` interface that can be used
to customize an `ApplicationContext` before it is used. If you need to use an initializer to customize an `ApplicationContext` before it is used. If you need to use an initializer
@ -451,7 +471,7 @@ to specify:
* The Tomcat `base directory` (`server.tomcat.basedir`) * The Tomcat `base directory` (`server.tomcat.basedir`)
## Customizing Logging ## Customizing Logging
Spring Boot uses [Commons Logging](commons.apache.org/logging/) for all internal logging, Spring Boot uses [Commons Logging](commons.apache.org/logging) for all internal logging,
but leaves the underlying log implementation open. Default configurations are provided for but leaves the underlying log implementation open. Default configurations are provided for
[Java Util Logging](http://docs.oracle.com/javase/7/docs/api/java/util/logging/package-summary.html), [Java Util Logging](http://docs.oracle.com/javase/7/docs/api/java/util/logging/package-summary.html),
[Log4J](http://logging.apache.org/log4j/) and [Logback](http://logback.qos.ch/). [Log4J](http://logging.apache.org/log4j/) and [Logback](http://logback.qos.ch/).

View File

@ -147,15 +147,24 @@ public class ConfigFileApplicationListener implements
PropertySource<?> defaultProperties = environment.getPropertySources().remove( PropertySource<?> defaultProperties = environment.getPropertySources().remove(
"defaultProperties"); "defaultProperties");
addActiveProfiles(environment); // Load to allow a file that defines active profiles to be considered
String firstPropertySourceName = loadInitial(environment, resourceLoader, String firstPropertySourceName = loadInitial(environment, resourceLoader,
candidates); candidates);
// Apply the active profiles (if any) from the first property source
if (environment.containsProperty(ACTIVE_PROFILES_PROPERTY)) {
activeProfilesFromProperty(environment,
environment.getProperty(ACTIVE_PROFILES_PROPERTY), true);
}
// Apply any profile additions from any source
activeProfileAdditionsFromAnySource(environment);
// Repeatedly load property sources in case additional profiles are activated // Repeatedly load property sources in case additional profiles are activated
int numberOfPropertySources; int numberOfPropertySources;
do { do {
numberOfPropertySources = environment.getPropertySources().size(); numberOfPropertySources = environment.getPropertySources().size();
addActiveProfiles(environment); activeProfileAdditionsFromAnySource(environment);
loadAgain(environment, resourceLoader, candidates, firstPropertySourceName); loadAgain(environment, resourceLoader, candidates, firstPropertySourceName);
} }
while (environment.getPropertySources().size() > numberOfPropertySources); while (environment.getPropertySources().size() > numberOfPropertySources);
@ -165,17 +174,22 @@ public class ConfigFileApplicationListener implements
} }
} }
/** private void activeProfileAdditionsFromAnySource(ConfigurableEnvironment environment) {
* @param environment
*/
private void addActiveProfiles(ConfigurableEnvironment environment) {
for (PropertySource<?> propertySource : environment.getPropertySources()) { for (PropertySource<?> propertySource : environment.getPropertySources()) {
if (propertySource.containsProperty(ACTIVE_PROFILES_PROPERTY)) { if (propertySource.containsProperty(ACTIVE_PROFILES_PROPERTY)) {
Object profiles = propertySource.getProperty(ACTIVE_PROFILES_PROPERTY); activeProfilesFromProperty(environment,
for (String profile : StringUtils.commaDelimitedListToSet(profiles propertySource.getProperty(ACTIVE_PROFILES_PROPERTY), false);
.toString())) { }
environment.addActiveProfile(profile); }
} }
private void activeProfilesFromProperty(ConfigurableEnvironment environment,
Object property, boolean addAll) {
for (String profile : StringUtils.commaDelimitedListToSet(property.toString())) {
boolean addition = profile.startsWith("+");
profile = (addition ? profile.substring(1) : profile);
if (addAll || addition) {
environment.addActiveProfile(profile);
} }
} }
} }

View File

@ -186,8 +186,7 @@ public class ConfigFileApplicationListenerTests {
"spring.profiles.active:prod"); "spring.profiles.active:prod");
this.initializer.setNames("testsetprofiles"); this.initializer.setNames("testsetprofiles");
this.initializer.onApplicationEvent(this.event); this.initializer.onApplicationEvent(this.event);
assertThat(this.environment.getActiveProfiles(), equalTo(new String[] { "prod", assertThat(this.environment.getActiveProfiles(), equalTo(new String[] { "prod" }));
"dev" }));
} }
@Test @Test
@ -356,6 +355,11 @@ public class ConfigFileApplicationListenerTests {
assertThat(context.getEnvironment().acceptsProfiles("activateprofile"), assertThat(context.getEnvironment().acceptsProfiles("activateprofile"),
equalTo(true)); equalTo(true));
assertThat(context.getEnvironment().acceptsProfiles("specific"), equalTo(true)); assertThat(context.getEnvironment().acceptsProfiles("specific"), equalTo(true));
assertThat(context.getEnvironment().acceptsProfiles("morespecific"),
equalTo(true));
assertThat(context.getEnvironment().acceptsProfiles("yetmorespecific"),
equalTo(true));
assertThat(context.getEnvironment().acceptsProfiles("missing"), equalTo(false));
} }
@Test @Test

View File

@ -1 +1 @@
spring.profiles.active=specific spring.profiles.active=+specific

View File

@ -0,0 +1 @@
spring.profiles.active=+yetmorespecific,missing

View File

@ -0,0 +1 @@
spring.profiles.active=+morespecific

View File

@ -1,3 +1,3 @@
spring: spring:
profiles: profiles:
active: a active: +a