diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/PlaceholderConfigurerSupport.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/PlaceholderConfigurerSupport.java
index a0152ed4478..f7223a9a1ce 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/config/PlaceholderConfigurerSupport.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/PlaceholderConfigurerSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -107,6 +107,8 @@ public abstract class PlaceholderConfigurerSupport extends PropertyResourceConfi
/** Defaults to {@value #DEFAULT_VALUE_SEPARATOR} */
protected String valueSeparator = DEFAULT_VALUE_SEPARATOR;
+ protected boolean trimValues = false;
+
protected String nullValue;
protected boolean ignoreUnresolvablePlaceholders = false;
@@ -142,6 +144,16 @@ public abstract class PlaceholderConfigurerSupport extends PropertyResourceConfi
this.valueSeparator = valueSeparator;
}
+ /**
+ * Specify whether to trim resolved values before applying them,
+ * removing superfluous whitespace from the beginning and end.
+ *
Default is {@code false}.
+ * @since 4.3
+ */
+ public void setTrimValues(boolean trimValues) {
+ this.trimValues = trimValues;
+ }
+
/**
* Set a value that should be treated as {@code null} when resolved
* as a placeholder value: e.g. "" (empty String) or "null".
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.java
index f98ce40e608..a0243a3396d 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -255,8 +255,11 @@ public class PropertyPlaceholderConfigurer extends PlaceholderConfigurerSupport
@Override
public String resolveStringValue(String strVal) throws BeansException {
- String value = this.helper.replacePlaceholders(strVal, this.resolver);
- return (value.equals(nullValue) ? null : value);
+ String resolved = this.helper.replacePlaceholders(strVal, this.resolver);
+ if (trimValues) {
+ resolved = resolved.trim();
+ }
+ return (resolved.equals(nullValue) ? null : resolved);
}
}
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/config/PropertyPlaceholderConfigurerTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/config/PropertyPlaceholderConfigurerTests.java
index 38a42d1d64e..903b34f1152 100644
--- a/spring-beans/src/test/java/org/springframework/beans/factory/config/PropertyPlaceholderConfigurerTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/config/PropertyPlaceholderConfigurerTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,11 +39,10 @@ import static org.springframework.beans.factory.support.BeanDefinitionReaderUtil
/**
* Unit tests for {@link PropertyPlaceholderConfigurer}.
*
- * @see PropertySourcesPlaceholderConfigurerTests
- * @see PropertyResourceConfigurerTests
* @author Chris Beams
*/
public class PropertyPlaceholderConfigurerTests {
+
private static final String P1 = "p1";
private static final String P1_LOCAL_PROPS_VAL = "p1LocalPropsVal";
private static final String P1_SYSTEM_PROPS_VAL = "p1SystemPropsVal";
@@ -55,11 +54,12 @@ public class PropertyPlaceholderConfigurerTests {
private AbstractBeanDefinition p1BeanDef;
+
@Before
public void setUp() {
p1BeanDef = rootBeanDefinition(TestBean.class)
- .addPropertyValue("name", "${"+P1+"}")
- .getBeanDefinition();
+ .addPropertyValue("name", "${" + P1 + "}")
+ .getBeanDefinition();
bf = new DefaultListableBeanFactory();
@@ -97,9 +97,9 @@ public class PropertyPlaceholderConfigurerTests {
public void resolveFromSystemProperties() {
getModifiableSystemEnvironment().put("otherKey", "systemValue");
p1BeanDef = rootBeanDefinition(TestBean.class)
- .addPropertyValue("name", "${"+P1+"}")
- .addPropertyValue("sex", "${otherKey}")
- .getBeanDefinition();
+ .addPropertyValue("name", "${" + P1 + "}")
+ .addPropertyValue("sex", "${otherKey}")
+ .getBeanDefinition();
registerWithGeneratedName(p1BeanDef, bf);
ppc.postProcessBeanFactory(bf);
TestBean bean = bf.getBean(TestBean.class);
@@ -167,9 +167,9 @@ public class PropertyPlaceholderConfigurerTests {
String P2_SYSTEM_ENV_VAL = "p2SystemEnvVal";
AbstractBeanDefinition p2BeanDef = rootBeanDefinition(TestBean.class)
- .addPropertyValue("name", "${"+P1+"}")
- .addPropertyValue("country", "${"+P2+"}")
- .getBeanDefinition();
+ .addPropertyValue("name", "${" + P1 + "}")
+ .addPropertyValue("country", "${" + P2 + "}")
+ .getBeanDefinition();
bf.registerBeanDefinition("p1Bean", p1BeanDef);
bf.registerBeanDefinition("p2Bean", p2BeanDef);
@@ -238,6 +238,33 @@ public class PropertyPlaceholderConfigurerTests {
getModifiableSystemEnvironment().remove("my.name");
}
+ @Test
+ public void trimValuesIsOffByDefault() {
+ PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
+ getModifiableSystemEnvironment().put("my.name", " myValue ");
+ DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
+ bf.registerBeanDefinition("testBean", rootBeanDefinition(TestBean.class)
+ .addPropertyValue("name", "${my.name}")
+ .getBeanDefinition());
+ ppc.postProcessBeanFactory(bf);
+ assertThat(bf.getBean(TestBean.class).getName(), equalTo(" myValue "));
+ getModifiableSystemEnvironment().remove("my.name");
+ }
+
+ @Test
+ public void trimValuesIsApplied() {
+ PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
+ ppc.setTrimValues(true);
+ getModifiableSystemEnvironment().put("my.name", " myValue ");
+ DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
+ bf.registerBeanDefinition("testBean", rootBeanDefinition(TestBean.class)
+ .addPropertyValue("name", "${my.name}")
+ .getBeanDefinition());
+ ppc.postProcessBeanFactory(bf);
+ assertThat(bf.getBean(TestBean.class).getName(), equalTo("myValue"));
+ getModifiableSystemEnvironment().remove("my.name");
+ }
+
@SuppressWarnings("unchecked")
private static Map getModifiableSystemEnvironment() {
@@ -253,7 +280,8 @@ public class PropertyPlaceholderConfigurerTests {
if (obj != null && obj.getClass().getName().equals("java.lang.ProcessEnvironment$StringEnvironment")) {
return (Map) obj;
}
- } catch (Exception ex) {
+ }
+ catch (Exception ex) {
throw new RuntimeException(ex);
}
}
@@ -263,8 +291,9 @@ public class PropertyPlaceholderConfigurerTests {
Class> processEnvironmentClass;
try {
processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
- } catch (Exception e) {
- throw new RuntimeException(e);
+ }
+ catch (Exception ex) {
+ throw new RuntimeException(ex);
}
try {
@@ -272,10 +301,12 @@ public class PropertyPlaceholderConfigurerTests {
theCaseInsensitiveEnvironmentField.setAccessible(true);
Object obj = theCaseInsensitiveEnvironmentField.get(null);
return (Map) obj;
- } catch (NoSuchFieldException e) {
+ }
+ catch (NoSuchFieldException ex) {
// do nothing
- } catch (Exception e) {
- throw new RuntimeException(e);
+ }
+ catch (Exception ex) {
+ throw new RuntimeException(ex);
}
try {
@@ -283,10 +314,12 @@ public class PropertyPlaceholderConfigurerTests {
theEnvironmentField.setAccessible(true);
Object obj = theEnvironmentField.get(null);
return (Map) obj;
- } catch (NoSuchFieldException e) {
+ }
+ catch (NoSuchFieldException ex) {
// do nothing
- } catch (Exception e) {
- throw new RuntimeException(e);
+ }
+ catch (Exception ex) {
+ throw new RuntimeException(ex);
}
throw new IllegalStateException();
diff --git a/spring-context/src/main/java/org/springframework/context/config/PropertyPlaceholderBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/context/config/PropertyPlaceholderBeanDefinitionParser.java
index f280159728a..cb38e6b0256 100644
--- a/spring-context/src/main/java/org/springframework/context/config/PropertyPlaceholderBeanDefinitionParser.java
+++ b/spring-context/src/main/java/org/springframework/context/config/PropertyPlaceholderBeanDefinitionParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -69,7 +69,9 @@ class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBea
if (element.hasAttribute("value-separator")) {
builder.addPropertyValue("valueSeparator", element.getAttribute("value-separator"));
}
-
+ if (element.hasAttribute("trim-values")) {
+ builder.addPropertyValue("trimValues", element.getAttribute("trim-values"));
+ }
if (element.hasAttribute("null-value")) {
builder.addPropertyValue("nullValue", element.getAttribute("null-value"));
}
diff --git a/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java b/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java
index 577eb93fdab..4a12a31e662 100644
--- a/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java
+++ b/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -167,9 +167,12 @@ public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerS
StringValueResolver valueResolver = new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
- String resolved = ignoreUnresolvablePlaceholders ?
+ String resolved = (ignoreUnresolvablePlaceholders ?
propertyResolver.resolvePlaceholders(strVal) :
- propertyResolver.resolveRequiredPlaceholders(strVal);
+ propertyResolver.resolveRequiredPlaceholders(strVal));
+ if (trimValues) {
+ resolved = resolved.trim();
+ }
return (resolved.equals(nullValue) ? null : resolved);
}
};
diff --git a/spring-context/src/main/resources/org/springframework/context/config/spring-context-4.3.xsd b/spring-context/src/main/resources/org/springframework/context/config/spring-context-4.3.xsd
index 0a3c1952e03..c7439e98455 100644
--- a/spring-context/src/main/resources/org/springframework/context/config/spring-context-4.3.xsd
+++ b/spring-context/src/main/resources/org/springframework/context/config/spring-context-4.3.xsd
@@ -149,6 +149,14 @@
+
+
+
+
+
diff --git a/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java b/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java
index e6a3b30443c..ba04db4931b 100644
--- a/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java
+++ b/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,14 +18,10 @@ package org.springframework.context.config;
import java.util.Calendar;
import java.util.Date;
-import java.util.Map;
import org.junit.After;
import org.junit.Test;
-import org.springframework.beans.factory.config.PlaceholderConfigurerSupport;
-import org.springframework.beans.factory.config.PropertyOverrideConfigurer;
-import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
@@ -53,9 +49,6 @@ public class ContextNamespaceHandlerTests {
public void propertyPlaceholder() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"contextNamespaceHandlerTests-replace.xml", getClass());
- Map beans = applicationContext
- .getBeansOfType(PlaceholderConfigurerSupport.class);
- assertFalse("No PropertyPlaceholderConfigurer found", beans.isEmpty());
assertEquals("bar", applicationContext.getBean("string"));
assertEquals("null", applicationContext.getBean("nullString"));
}
@@ -66,9 +59,6 @@ public class ContextNamespaceHandlerTests {
try {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"contextNamespaceHandlerTests-system.xml", getClass());
- Map beans = applicationContext
- .getBeansOfType(PropertyPlaceholderConfigurer.class);
- assertFalse("No PropertyPlaceholderConfigurer found", beans.isEmpty());
assertEquals("spam", applicationContext.getBean("string"));
assertEquals("none", applicationContext.getBean("fallback"));
}
@@ -86,9 +76,6 @@ public class ContextNamespaceHandlerTests {
applicationContext.setEnvironment(env);
applicationContext.load(new ClassPathResource("contextNamespaceHandlerTests-simple.xml", getClass()));
applicationContext.refresh();
- Map beans = applicationContext
- .getBeansOfType(PlaceholderConfigurerSupport.class);
- assertFalse("No PropertyPlaceholderConfigurer found", beans.isEmpty());
assertEquals("spam", applicationContext.getBean("string"));
assertEquals("none", applicationContext.getBean("fallback"));
}
@@ -97,9 +84,6 @@ public class ContextNamespaceHandlerTests {
public void propertyPlaceholderLocation() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"contextNamespaceHandlerTests-location.xml", getClass());
- Map beans = applicationContext
- .getBeansOfType(PropertyPlaceholderConfigurer.class);
- assertFalse("No PropertyPlaceholderConfigurer found", beans.isEmpty());
assertEquals("bar", applicationContext.getBean("foo"));
assertEquals("foo", applicationContext.getBean("bar"));
assertEquals("maps", applicationContext.getBean("spam"));
@@ -109,9 +93,6 @@ public class ContextNamespaceHandlerTests {
public void propertyPlaceholderIgnored() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"contextNamespaceHandlerTests-replace-ignore.xml", getClass());
- Map beans = applicationContext
- .getBeansOfType(PlaceholderConfigurerSupport.class);
- assertFalse("No PropertyPlaceholderConfigurer found", beans.isEmpty());
assertEquals("${bar}", applicationContext.getBean("string"));
assertEquals("null", applicationContext.getBean("nullString"));
}
@@ -120,9 +101,6 @@ public class ContextNamespaceHandlerTests {
public void propertyOverride() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"contextNamespaceHandlerTests-override.xml", getClass());
- Map beans = applicationContext
- .getBeansOfType(PropertyOverrideConfigurer.class);
- assertFalse("No PropertyOverrideConfigurer found", beans.isEmpty());
Date date = (Date) applicationContext.getBean("date");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
diff --git a/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java b/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java
index e11ae4769bb..030446306fe 100644
--- a/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java
+++ b/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.context.support;
+import java.util.Optional;
import java.util.Properties;
import org.junit.Rule;
@@ -24,6 +25,7 @@ import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
@@ -39,6 +41,7 @@ import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
/**
* @author Chris Beams
+ * @author Juergen Hoeller
* @since 3.1
*/
public class PropertySourcesPlaceholderConfigurerTests {
@@ -46,6 +49,7 @@ public class PropertySourcesPlaceholderConfigurerTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
+
@Test
public void replacementFromEnvironmentProperties() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -57,8 +61,7 @@ public class PropertySourcesPlaceholderConfigurerTests {
MockEnvironment env = new MockEnvironment();
env.setProperty("my.name", "myValue");
- PropertySourcesPlaceholderConfigurer ppc =
- new PropertySourcesPlaceholderConfigurer();
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
ppc.setEnvironment(env);
ppc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), equalTo("myValue"));
@@ -73,10 +76,10 @@ public class PropertySourcesPlaceholderConfigurerTests {
.addPropertyValue("name", "${my.name}")
.getBeanDefinition());
- PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer();
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
Resource resource = new ClassPathResource("PropertySourcesPlaceholderConfigurerTests.properties", this.getClass());
- pc.setLocation(resource);
- pc.postProcessBeanFactory(bf);
+ ppc.setLocation(resource);
+ ppc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), equalTo("foo"));
}
@@ -101,11 +104,11 @@ public class PropertySourcesPlaceholderConfigurerTests {
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new MockPropertySource().withProperty("my.name", "foo"));
- PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer();
- pc.setPropertySources(propertySources);
- pc.postProcessBeanFactory(bf);
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
+ ppc.setPropertySources(propertySources);
+ ppc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), equalTo("foo"));
- assertEquals(pc.getAppliedPropertySources().iterator().next(), propertySources.iterator().next());
+ assertEquals(ppc.getAppliedPropertySources().iterator().next(), propertySources.iterator().next());
}
@Test
@@ -119,13 +122,13 @@ public class PropertySourcesPlaceholderConfigurerTests {
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new MockPropertySource());
- PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer();
- pc.setPropertySources(propertySources);
- pc.setEnvironment(new MockEnvironment().withProperty("my.name", "env"));
- pc.setIgnoreUnresolvablePlaceholders(true);
- pc.postProcessBeanFactory(bf);
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
+ ppc.setPropertySources(propertySources);
+ ppc.setEnvironment(new MockEnvironment().withProperty("my.name", "env"));
+ ppc.setIgnoreUnresolvablePlaceholders(true);
+ ppc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), equalTo("${my.name}"));
- assertEquals(pc.getAppliedPropertySources().iterator().next(), propertySources.iterator().next());
+ assertEquals(ppc.getAppliedPropertySources().iterator().next(), propertySources.iterator().next());
}
@Test
@@ -140,17 +143,17 @@ public class PropertySourcesPlaceholderConfigurerTests {
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new MockPropertySource());
- PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer();
- pc.setPropertySources(propertySources);
- pc.setProperties(new Properties() {{
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
+ ppc.setPropertySources(propertySources);
+ ppc.setProperties(new Properties() {{
put("my.name", "local");
}});
- pc.setIgnoreUnresolvablePlaceholders(true);
- pc.postProcessBeanFactory(bf);
+ ppc.setIgnoreUnresolvablePlaceholders(true);
+ ppc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), equalTo("${my.name}"));
}
- @Test(expected=BeanDefinitionStoreException.class)
+ @Test(expected = BeanDefinitionStoreException.class)
public void ignoreUnresolvablePlaceholders_falseIsDefault() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerBeanDefinition("testBean",
@@ -158,9 +161,9 @@ public class PropertySourcesPlaceholderConfigurerTests {
.addPropertyValue("name", "${my.name}")
.getBeanDefinition());
- PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer();
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
//pc.setIgnoreUnresolvablePlaceholders(false); // the default
- pc.postProcessBeanFactory(bf); // should throw
+ ppc.postProcessBeanFactory(bf); // should throw
}
@Test
@@ -171,13 +174,13 @@ public class PropertySourcesPlaceholderConfigurerTests {
.addPropertyValue("name", "${my.name}")
.getBeanDefinition());
- PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer();
- pc.setIgnoreUnresolvablePlaceholders(true);
- pc.postProcessBeanFactory(bf);
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
+ ppc.setIgnoreUnresolvablePlaceholders(true);
+ ppc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), equalTo("${my.name}"));
}
- @Test(expected=BeanDefinitionStoreException.class)
+ @Test(expected = BeanDefinitionStoreException.class)
@SuppressWarnings("serial")
public void nestedUnresolvablePlaceholder() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -186,11 +189,11 @@ public class PropertySourcesPlaceholderConfigurerTests {
.addPropertyValue("name", "${my.name}")
.getBeanDefinition());
- PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer();
- pc.setProperties(new Properties() {{
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
+ ppc.setProperties(new Properties() {{
put("my.name", "${bogus}");
}});
- pc.postProcessBeanFactory(bf); // should throw
+ ppc.postProcessBeanFactory(bf); // should throw
}
@Test
@@ -202,12 +205,12 @@ public class PropertySourcesPlaceholderConfigurerTests {
.addPropertyValue("name", "${my.name}")
.getBeanDefinition());
- PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer();
- pc.setProperties(new Properties() {{
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
+ ppc.setProperties(new Properties() {{
put("my.name", "${bogus}");
}});
- pc.setIgnoreUnresolvablePlaceholders(true);
- pc.postProcessBeanFactory(bf);
+ ppc.setIgnoreUnresolvablePlaceholders(true);
+ ppc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), equalTo("${bogus}"));
}
@@ -295,6 +298,31 @@ public class PropertySourcesPlaceholderConfigurerTests {
assertThat(bf.getBean(TestBean.class).getName(), nullValue());
}
+ @Test
+ public void trimValuesIsOffByDefault() {
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
+ DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
+ bf.registerBeanDefinition("testBean", rootBeanDefinition(TestBean.class)
+ .addPropertyValue("name", "${my.name}")
+ .getBeanDefinition());
+ ppc.setEnvironment(new MockEnvironment().withProperty("my.name", " myValue "));
+ ppc.postProcessBeanFactory(bf);
+ assertThat(bf.getBean(TestBean.class).getName(), equalTo(" myValue "));
+ }
+
+ @Test
+ public void trimValuesIsApplied() {
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
+ ppc.setTrimValues(true);
+ DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
+ bf.registerBeanDefinition("testBean", rootBeanDefinition(TestBean.class)
+ .addPropertyValue("name", "${my.name}")
+ .getBeanDefinition());
+ ppc.setEnvironment(new MockEnvironment().withProperty("my.name", " myValue "));
+ ppc.postProcessBeanFactory(bf);
+ assertThat(bf.getBean(TestBean.class).getName(), equalTo("myValue"));
+ }
+
@Test
public void getAppliedPropertySourcesTooEarly() throws Exception {
PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
@@ -308,7 +336,7 @@ public class PropertySourcesPlaceholderConfigurerTests {
PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
ClassPathResource doesNotHave = new ClassPathResource("test.properties", getClass());
ClassPathResource setToTrue = new ClassPathResource("placeholder.properties", getClass());
- ppc.setLocations(new Resource[] { doesNotHave, setToTrue });
+ ppc.setLocations(doesNotHave, setToTrue);
ppc.setIgnoreResourceNotFound(true);
ppc.setIgnoreUnresolvablePlaceholders(true);
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -320,4 +348,57 @@ public class PropertySourcesPlaceholderConfigurerTests {
assertThat(bf.getBean(TestBean.class).isJedi(), equalTo(true));
}
+ @Test
+ public void optionalPropertyWithValue() {
+ DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
+ bf.setConversionService(new DefaultConversionService());
+ bf.registerBeanDefinition("testBean",
+ genericBeanDefinition(OptionalTestBean.class)
+ .addPropertyValue("name", "${my.name}")
+ .getBeanDefinition());
+
+ MockEnvironment env = new MockEnvironment();
+ env.setProperty("my.name", "myValue");
+
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
+ ppc.setEnvironment(env);
+ ppc.setIgnoreUnresolvablePlaceholders(true);
+ ppc.postProcessBeanFactory(bf);
+ assertThat(bf.getBean(OptionalTestBean.class).getName(), equalTo(Optional.of("myValue")));
+ }
+
+ @Test
+ public void optionalPropertyWithoutValue() {
+ DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
+ bf.setConversionService(new DefaultConversionService());
+ bf.registerBeanDefinition("testBean",
+ genericBeanDefinition(OptionalTestBean.class)
+ .addPropertyValue("name", "${my.name}")
+ .getBeanDefinition());
+
+ MockEnvironment env = new MockEnvironment();
+ env.setProperty("my.name", "");
+
+ PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
+ ppc.setEnvironment(env);
+ ppc.setIgnoreUnresolvablePlaceholders(true);
+ ppc.setNullValue("");
+ ppc.postProcessBeanFactory(bf);
+ assertThat(bf.getBean(OptionalTestBean.class).getName(), equalTo(Optional.empty()));
+ }
+
+
+ private static class OptionalTestBean {
+
+ private Optional name;
+
+ public Optional getName() {
+ return name;
+ }
+
+ public void setName(Optional name) {
+ this.name = name;
+ }
+ }
+
}
diff --git a/spring-context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-location.xml b/spring-context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-location.xml
index e90a5e42b34..f6a4be6fc05 100644
--- a/spring-context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-location.xml
+++ b/spring-context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-location.xml
@@ -2,12 +2,12 @@
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
+ file-encoding="ISO-8859-1" trim-values="true"/>
diff --git a/spring-context/src/test/resources/org/springframework/context/config/test-bar.properties b/spring-context/src/test/resources/org/springframework/context/config/test-bar.properties
index b0e291695e7..6d7afb4ec9f 100644
--- a/spring-context/src/test/resources/org/springframework/context/config/test-bar.properties
+++ b/spring-context/src/test/resources/org/springframework/context/config/test-bar.properties
@@ -1,2 +1,2 @@
-bar=foo
-spam=maps
+bar= foo\t
+spam=\tmaps