Skip to content

Commit dc17946

Browse files
committed
Add prefix support for environment variables
Include a filter in ConfigurationPropertiesBindingPostProcessor that checks if the property "spring.property.prefix" exists (not blank) and filter the system properties ensuring that the properties with the prefix are available on property binding. Fixes #3450
1 parent d22265b commit dc17946

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

spring-boot/src/main/java/org/springframework/boot/SpringApplication.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ public class SpringApplication {
177177

178178
private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless";
179179

180+
public static final String PROPERTY_BINDING_PREFIX_PROPERTY = "spring.property.prefix";
181+
180182
private static final Banner DEFAULT_BANNER = new SpringBootBanner();
181183

182184
private static final Set<String> SERVLET_ENVIRONMENT_SOURCE_NAMES;
@@ -1052,6 +1054,17 @@ public void setEnvironment(ConfigurableEnvironment environment) {
10521054
this.environment = environment;
10531055
}
10541056

1057+
/**
1058+
+ * Sets the environment variables prefix that will be used to filter those variables
1059+
+ * for this application.
1060+
+ * @param environmentPrefix the prefix
1061+
+ */
1062+
public void setEnvironmentPrefix(String environmentPrefix) {
1063+
if(environmentPrefix != null && !"".equals(environmentPrefix)) {
1064+
System.setProperty(PROPERTY_BINDING_PREFIX_PROPERTY, environmentPrefix);
1065+
}
1066+
}
1067+
10551068
/**
10561069
* Returns a mutable set of the sources that will be added to an ApplicationContext
10571070
* when {@link #run(String...)} is called.

spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.IOException;
2020
import java.util.Collections;
21+
import java.util.HashMap;
2122
import java.util.Iterator;
2223
import java.util.List;
2324
import java.util.Map;
@@ -32,6 +33,7 @@
3233
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
3334
import org.springframework.beans.factory.annotation.Autowired;
3435
import org.springframework.beans.factory.config.BeanPostProcessor;
36+
import org.springframework.boot.SpringApplication;
3537
import org.springframework.boot.bind.PropertiesConfigurationFactory;
3638
import org.springframework.boot.env.PropertySourcesLoader;
3739
import org.springframework.context.ApplicationContext;
@@ -55,6 +57,7 @@
5557
import org.springframework.core.env.PropertySource;
5658
import org.springframework.core.env.PropertySources;
5759
import org.springframework.core.env.StandardEnvironment;
60+
import org.springframework.core.env.SystemEnvironmentPropertySource;
5861
import org.springframework.core.io.DefaultResourceLoader;
5962
import org.springframework.core.io.Resource;
6063
import org.springframework.core.io.ResourceLoader;
@@ -243,6 +246,13 @@ private void freeLocalValidator() {
243246
}
244247

245248
private PropertySources deducePropertySources() {
249+
String prefix = this.environment
250+
.getProperty(SpringApplication.PROPERTY_BINDING_PREFIX_PROPERTY, "");
251+
if (prefix != null && !"".equals(prefix)) {
252+
filterSystemEnvironmentPropertySourceByPrefix(
253+
(ConfigurableEnvironment) this.environment, prefix);
254+
}
255+
246256
PropertySourcesPlaceholderConfigurer configurer = getSinglePropertySourcesPlaceholderConfigurer();
247257
if (configurer != null) {
248258
// Flatten the sources into a single list so they can be iterated
@@ -271,6 +281,28 @@ private PropertySourcesPlaceholderConfigurer getSinglePropertySourcesPlaceholder
271281
return null;
272282
}
273283

284+
private void filterSystemEnvironmentPropertySourceByPrefix(
285+
ConfigurableEnvironment environment, String prefix) {
286+
final Map<String, Object> environmentProperties = environment.getSystemProperties();
287+
final Map<String, Object> filteredSystemProperties = new HashMap<String, Object>(
288+
environmentProperties.size());
289+
290+
for (String key : environmentProperties.keySet()) {
291+
if (key.startsWith(prefix)) {
292+
filteredSystemProperties.put(key.substring(prefix.length()),
293+
environmentProperties.get(key));
294+
} else {
295+
filteredSystemProperties.put(key, environmentProperties.get(key));
296+
}
297+
}
298+
299+
environment.getPropertySources()
300+
.replace(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
301+
new SystemEnvironmentPropertySource(
302+
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
303+
filteredSystemProperties));
304+
}
305+
274306
private <T> T getOptionalBean(String name, Class<T> type) {
275307
try {
276308
return this.beanFactory.getBean(name, type);

spring-boot/src/test/java/org/springframework/boot/context/properties/EnableConfigurationPropertiesTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.junit.rules.ExpectedException;
3131

3232
import org.springframework.beans.factory.annotation.Autowired;
33+
import org.springframework.boot.SpringApplication;
3334
import org.springframework.boot.testutil.EnvironmentTestUtils;
3435
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3536
import org.springframework.context.annotation.Bean;
@@ -39,6 +40,7 @@
3940
import org.springframework.stereotype.Component;
4041
import org.springframework.validation.BindException;
4142

43+
import static org.junit.Assert.assertEquals;
4244
import static org.assertj.core.api.Assertions.assertThat;
4345

4446
/**
@@ -80,6 +82,18 @@ public void testSystemPropertiesBinding() {
8082
assertThat(this.context.getBean(TestProperties.class).name).isEqualTo("foo");
8183
}
8284

85+
@Test
86+
public void testSystemPropertiesWithPrefixBinding() {
87+
this.context.register(TestConfiguration.class);
88+
System.setProperty(SpringApplication.PROPERTY_BINDING_PREFIX_PROPERTY, "bar_");
89+
System.setProperty("bar_name", "foo");
90+
this.context.refresh();
91+
assertEquals(1, this.context.getBeanNamesForType(TestProperties.class).length);
92+
assertEquals("foo", this.context.getBean(TestProperties.class).name);
93+
assertEquals("foo",
94+
this.context.getEnvironment().getSystemProperties().get("bar_name"));
95+
}
96+
8397
@Test
8498
public void testNestedSystemPropertiesBinding() {
8599
this.context.register(NestedConfiguration.class);

0 commit comments

Comments
 (0)