Commit a79ff19b authored by Phillip Webb's avatar Phillip Webb Committed by Dave Syer

Replace confusing '+' profile syntax.

Replace the confusing `spring.profiles.active` `+` syntax with a new
`spring.profiles.include` property.

Fixes gh-483, Fixes gh-534
parent 7be2d97d
...@@ -534,10 +534,10 @@ be marked with `@Profile` to limit when it is loaded: ...@@ -534,10 +534,10 @@ be marked with `@Profile` to limit when it is loaded:
} }
---- ----
Spring Boot takes this a stage further, in that you can use a `spring.profiles.active` In the normal Spring way, you can use a `spring.profiles.active`
`Environment` property to specify which profiles are active. You can specify the property `Environment` property to specify which profiles are active. You can
in any of the usual ways, for example you could include it in your specify the property in any of the usual ways, for example you could
`application.properties`: include it in your `application.properties`:
[source,properties,indent=0] [source,properties,indent=0]
---- ----
...@@ -556,7 +556,10 @@ active profiles in `application.properties` then *replace* them using the comman ...@@ -556,7 +556,10 @@ active profiles in `application.properties` then *replace* them using the comman
switch. switch.
Sometimes it is useful to have profile specific properties that *add* to the active 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. profiles rather than replace them. The `spring.profiles.include` property can be used
to unconditionally add active profiles. The `SpringApplication` entry point also has
a Java API for setting additional profiles (i.e. on top of those activated by the
`spring.profiles.active` property): see the `setAdditionalProfiles()` method.
For example, when an application with following properties is run using the switch 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: `--spring.profiles.active=prod` the `proddb` and `prodmq` profiles will also be activated:
...@@ -567,7 +570,7 @@ For example, when an application with following properties is run using the swit ...@@ -567,7 +570,7 @@ For example, when an application with following properties is run using the swit
my.property: fromyamlfile my.property: fromyamlfile
--- ---
spring.profiles: prod spring.profiles: prod
spring.profiles.active: +proddb,+prodmq spring.profiles.include: proddb,prodmq
---- ----
......
...@@ -92,6 +92,8 @@ public class ConfigFileApplicationListener implements ...@@ -92,6 +92,8 @@ public class ConfigFileApplicationListener implements
private static final String ACTIVE_PROFILES_PROPERTY = "spring.profiles.active"; private static final String ACTIVE_PROFILES_PROPERTY = "spring.profiles.active";
private static final String INCLUDE_PROFILES_PROPERTY = "spring.profiles.include";
private static final String CONFIG_NAME_PROPERTY = "spring.config.name"; private static final String CONFIG_NAME_PROPERTY = "spring.config.name";
private static final String CONFIG_LOCATION_PROPERTY = "spring.config.location"; private static final String CONFIG_LOCATION_PROPERTY = "spring.config.location";
...@@ -274,9 +276,9 @@ public class ConfigFileApplicationListener implements ...@@ -274,9 +276,9 @@ public class ConfigFileApplicationListener implements
if (this.environment.containsProperty(ACTIVE_PROFILES_PROPERTY)) { if (this.environment.containsProperty(ACTIVE_PROFILES_PROPERTY)) {
// Any pre-existing active profiles set via property sources (e.g. System // Any pre-existing active profiles set via property sources (e.g. System
// properties) take precedence over those added in config files (unless // properties) take precedence over those added in config files.
// latter are prefixed with "+"). maybeActivateProfiles(this.environment
addActiveProfiles(this.environment.getProperty(ACTIVE_PROFILES_PROPERTY)); .getProperty(ACTIVE_PROFILES_PROPERTY));
} }
else { else {
// Pre-existing active profiles set via Environment.setActiveProfiles() // Pre-existing active profiles set via Environment.setActiveProfiles()
...@@ -330,36 +332,46 @@ public class ConfigFileApplicationListener implements ...@@ -330,36 +332,46 @@ public class ConfigFileApplicationListener implements
PropertySource<?> propertySource = this.propertiesLoader.load(resource, PropertySource<?> propertySource = this.propertiesLoader.load(resource,
name, profile); name, profile);
if (propertySource != null) { if (propertySource != null) {
addActiveProfiles(propertySource maybeActivateProfiles(propertySource
.getProperty(ACTIVE_PROFILES_PROPERTY)); .getProperty(ACTIVE_PROFILES_PROPERTY));
addIncludeProfiles(propertySource
.getProperty(INCLUDE_PROFILES_PROPERTY));
} }
return propertySource; return propertySource;
} }
return null; return null;
} }
private void addActiveProfiles(Object property) { private void maybeActivateProfiles(Object value) {
String profiles = (property == null ? null : property.toString()); if (!this.activatedProfiles == true) {
boolean profilesNotActivatedWhenCalled = !this.activatedProfiles; Set<String> profiles = getProfilesForValue(value);
for (String profile : asResolvedSet(profiles, null)) { activateProfiles(profiles);
// A profile name prefixed with "+" is always added even if it is if (profiles.size() > 0) {
// activated in a config file (without the "+" it can be disabled
// by an explicit Environment property set before the file was
// processed).
boolean addition = profile.startsWith("+");
profile = (addition ? profile.substring(1) : profile);
if (profilesNotActivatedWhenCalled || addition) {
this.profiles.add(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;
} }
} }
} }
private void addIncludeProfiles(Object value) {
Set<String> profiles = getProfilesForValue(value);
activateProfiles(profiles);
}
private Set<String> getProfilesForValue(Object property) {
return asResolvedSet((property == null ? null : property.toString()), null);
}
private void activateProfiles(Set<String> profiles) {
for (String profile : profiles) {
this.profiles.add(profile);
if (!this.environment.acceptsProfiles(profile)) {
// If it's already accepted we assume the order was set
// intentionally
prependProfile(this.environment, profile);
}
}
}
private void prependProfile(ConfigurableEnvironment environment, String profile) { private void prependProfile(ConfigurableEnvironment environment, String profile) {
Set<String> profiles = new LinkedHashSet<String>(); Set<String> profiles = new LinkedHashSet<String>();
environment.getActiveProfiles(); // ensure they are initialized environment.getActiveProfiles(); // ensure they are initialized
......
...@@ -433,8 +433,8 @@ public class ConfigFileApplicationListenerTests { ...@@ -433,8 +433,8 @@ public class ConfigFileApplicationListenerTests {
SpringApplication application = new SpringApplication(Config.class); SpringApplication application = new SpringApplication(Config.class);
application.setWebEnvironment(false); application.setWebEnvironment(false);
ConfigurableApplicationContext context = application ConfigurableApplicationContext context = application
.run("--spring.profiles.active=activateprofile"); .run("--spring.profiles.active=includeprofile");
assertThat(context.getEnvironment(), acceptsProfiles("activateprofile")); assertThat(context.getEnvironment(), acceptsProfiles("includeprofile"));
assertThat(context.getEnvironment(), acceptsProfiles("specific")); assertThat(context.getEnvironment(), acceptsProfiles("specific"));
assertThat(context.getEnvironment(), acceptsProfiles("morespecific")); assertThat(context.getEnvironment(), acceptsProfiles("morespecific"));
assertThat(context.getEnvironment(), acceptsProfiles("yetmorespecific")); assertThat(context.getEnvironment(), acceptsProfiles("yetmorespecific"));
......
spring.profiles.active=+yetmorespecific,missing spring.profiles.include=yetmorespecific
spring.profiles.active=missing
spring.profiles.active=+morespecific spring.profiles.include=morespecific
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