From a79ff19b00a3b975ba8506624a4e9abd56c2b92a Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 19 Mar 2014 18:08:10 -0700 Subject: [PATCH] Replace confusing '+' profile syntax. Replace the confusing `spring.profiles.active` `+` syntax with a new `spring.profiles.include` property. Fixes gh-483, Fixes gh-534 --- .../main/asciidoc/spring-boot-features.adoc | 15 +++--- .../config/ConfigFileApplicationListener.java | 54 +++++++++++-------- .../ConfigFileApplicationListenerTests.java | 4 +- .../application-activateprofile.properties | 1 - .../application-includeprofile.properties | 1 + .../application-morespecific.properties | 3 +- .../resources/application-specific.properties | 2 +- .../enableprofileviaapplicationproperties.yml | 2 +- 8 files changed, 49 insertions(+), 33 deletions(-) delete mode 100644 spring-boot/src/test/resources/application-activateprofile.properties create mode 100644 spring-boot/src/test/resources/application-includeprofile.properties diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 4c53d3645b5..80ceffe7c07 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -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` -`Environment` property to specify which profiles are active. You can specify the property -in any of the usual ways, for example you could include it in your -`application.properties`: +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 in any of the usual ways, for example you could +include it in your `application.properties`: [source,properties,indent=0] ---- @@ -556,7 +556,10 @@ active profiles in `application.properties` then *replace* them using the comman 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. +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 `--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 my.property: fromyamlfile --- spring.profiles: prod - spring.profiles.active: +proddb,+prodmq + spring.profiles.include: proddb,prodmq ---- diff --git a/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java b/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java index 1c256fb44b2..4f40702683c 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java @@ -92,6 +92,8 @@ public class ConfigFileApplicationListener implements 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_LOCATION_PROPERTY = "spring.config.location"; @@ -274,9 +276,9 @@ public class ConfigFileApplicationListener implements 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 (unless - // latter are prefixed with "+"). - addActiveProfiles(this.environment.getProperty(ACTIVE_PROFILES_PROPERTY)); + // properties) take precedence over those added in config files. + maybeActivateProfiles(this.environment + .getProperty(ACTIVE_PROFILES_PROPERTY)); } else { // Pre-existing active profiles set via Environment.setActiveProfiles() @@ -330,36 +332,46 @@ public class ConfigFileApplicationListener implements PropertySource propertySource = this.propertiesLoader.load(resource, name, profile); if (propertySource != null) { - addActiveProfiles(propertySource + maybeActivateProfiles(propertySource .getProperty(ACTIVE_PROFILES_PROPERTY)); + addIncludeProfiles(propertySource + .getProperty(INCLUDE_PROFILES_PROPERTY)); } return propertySource; } return null; } - private void addActiveProfiles(Object property) { - String profiles = (property == null ? null : property.toString()); - boolean profilesNotActivatedWhenCalled = !this.activatedProfiles; - for (String profile : asResolvedSet(profiles, null)) { - // A profile name prefixed with "+" is always added even if it is - // 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); - } + private void maybeActivateProfiles(Object value) { + if (!this.activatedProfiles == true) { + Set profiles = getProfilesForValue(value); + activateProfiles(profiles); + if (profiles.size() > 0) { this.activatedProfiles = true; } } } + private void addIncludeProfiles(Object value) { + Set profiles = getProfilesForValue(value); + activateProfiles(profiles); + } + + private Set getProfilesForValue(Object property) { + return asResolvedSet((property == null ? null : property.toString()), null); + } + + private void activateProfiles(Set 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) { Set profiles = new LinkedHashSet(); environment.getActiveProfiles(); // ensure they are initialized diff --git a/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java b/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java index 6a8aefa6ea8..0257b768ea9 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java @@ -433,8 +433,8 @@ public class ConfigFileApplicationListenerTests { SpringApplication application = new SpringApplication(Config.class); application.setWebEnvironment(false); ConfigurableApplicationContext context = application - .run("--spring.profiles.active=activateprofile"); - assertThat(context.getEnvironment(), acceptsProfiles("activateprofile")); + .run("--spring.profiles.active=includeprofile"); + assertThat(context.getEnvironment(), acceptsProfiles("includeprofile")); assertThat(context.getEnvironment(), acceptsProfiles("specific")); assertThat(context.getEnvironment(), acceptsProfiles("morespecific")); assertThat(context.getEnvironment(), acceptsProfiles("yetmorespecific")); diff --git a/spring-boot/src/test/resources/application-activateprofile.properties b/spring-boot/src/test/resources/application-activateprofile.properties deleted file mode 100644 index 3fad5d00432..00000000000 --- a/spring-boot/src/test/resources/application-activateprofile.properties +++ /dev/null @@ -1 +0,0 @@ -spring.profiles.active=+specific diff --git a/spring-boot/src/test/resources/application-includeprofile.properties b/spring-boot/src/test/resources/application-includeprofile.properties new file mode 100644 index 00000000000..213a72823c1 --- /dev/null +++ b/spring-boot/src/test/resources/application-includeprofile.properties @@ -0,0 +1 @@ +spring.profiles.include=specific diff --git a/spring-boot/src/test/resources/application-morespecific.properties b/spring-boot/src/test/resources/application-morespecific.properties index 0d1f6ccb978..65b26f856f4 100644 --- a/spring-boot/src/test/resources/application-morespecific.properties +++ b/spring-boot/src/test/resources/application-morespecific.properties @@ -1 +1,2 @@ -spring.profiles.active=+yetmorespecific,missing +spring.profiles.include=yetmorespecific +spring.profiles.active=missing diff --git a/spring-boot/src/test/resources/application-specific.properties b/spring-boot/src/test/resources/application-specific.properties index 51cf719b6bc..6fc460d83cc 100644 --- a/spring-boot/src/test/resources/application-specific.properties +++ b/spring-boot/src/test/resources/application-specific.properties @@ -1 +1 @@ -spring.profiles.active=+morespecific +spring.profiles.include=morespecific diff --git a/spring-boot/src/test/resources/enableprofileviaapplicationproperties.yml b/spring-boot/src/test/resources/enableprofileviaapplicationproperties.yml index 74f7f5b6f15..2e88b34de44 100644 --- a/spring-boot/src/test/resources/enableprofileviaapplicationproperties.yml +++ b/spring-boot/src/test/resources/enableprofileviaapplicationproperties.yml @@ -1,3 +1,3 @@ spring: profiles: - active: +a + include: a