Add flag to PropertiesConfigurationFactory to switch off placeholder resolution
The default behaviour is unchanged, but it is useful for some applications to be able to bind without placeholder resolution (e.g. to prevent exposing system environment variables, if the bound object is being sent over the wire).
This commit is contained in:
parent
d1fd79cfa3
commit
26a90c1d24
Notes:
Phillip Webb
2016-09-20 14:14:52 -07:00
gh-6964
|
|
@ -86,6 +86,8 @@ public class PropertiesConfigurationFactory<T>
|
|||
|
||||
private ConversionService conversionService;
|
||||
|
||||
private boolean resolvePlaceholders = true;
|
||||
|
||||
/**
|
||||
* Create a new {@link PropertiesConfigurationFactory} instance.
|
||||
* @param target the target object to bind too
|
||||
|
|
@ -203,6 +205,16 @@ public class PropertiesConfigurationFactory<T>
|
|||
this.exceptionIfInvalid = exceptionIfInvalid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag to indicate that placeholders should be replaced during binding. Default is
|
||||
* true.
|
||||
*
|
||||
* @param resolvePlaceholders flag value
|
||||
*/
|
||||
public void setResolvePlaceholders(boolean resolvePlaceholders) {
|
||||
this.resolvePlaceholders = resolvePlaceholders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
bindPropertiesToTarget();
|
||||
|
|
@ -322,7 +334,8 @@ public class PropertiesConfigurationFactory<T>
|
|||
Iterable<String> relaxedTargetNames) {
|
||||
PropertyNamePatternsMatcher includes = getPropertyNamePatternsMatcher(names,
|
||||
relaxedTargetNames);
|
||||
return new PropertySourcesPropertyValues(this.propertySources, names, includes);
|
||||
return new PropertySourcesPropertyValues(this.propertySources, names, includes,
|
||||
this.resolvePlaceholders);
|
||||
}
|
||||
|
||||
private PropertyNamePatternsMatcher getPropertyNamePatternsMatcher(Set<String> names,
|
||||
|
|
|
|||
|
|
@ -56,12 +56,15 @@ public class PropertySourcesPropertyValues implements PropertyValues {
|
|||
|
||||
private final ConcurrentHashMap<String, PropertySource<?>> collectionOwners = new ConcurrentHashMap<String, PropertySource<?>>();
|
||||
|
||||
private boolean resolvePlaceholders = true;
|
||||
|
||||
/**
|
||||
* Create a new PropertyValues from the given PropertySources.
|
||||
* @param propertySources a PropertySources instance
|
||||
*/
|
||||
public PropertySourcesPropertyValues(PropertySources propertySources) {
|
||||
this(propertySources, (Collection<String>) null, PropertyNamePatternsMatcher.ALL);
|
||||
this(propertySources, (Collection<String>) null, PropertyNamePatternsMatcher.ALL,
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -76,7 +79,7 @@ public class PropertySourcesPropertyValues implements PropertyValues {
|
|||
Collection<String> includePatterns,
|
||||
Collection<String> nonEnumerableFallbackNames) {
|
||||
this(propertySources, nonEnumerableFallbackNames,
|
||||
new PatternPropertyNamePatternsMatcher(includePatterns));
|
||||
new PatternPropertyNamePatternsMatcher(includePatterns), true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -85,15 +88,17 @@ public class PropertySourcesPropertyValues implements PropertyValues {
|
|||
* @param nonEnumerableFallbackNames the property names to try in lieu of an
|
||||
* {@link EnumerablePropertySource}.
|
||||
* @param includes the property name patterns to include
|
||||
* @param resolvePlaceholders flag to indicate the placeholders should be resolved
|
||||
*/
|
||||
PropertySourcesPropertyValues(PropertySources propertySources,
|
||||
Collection<String> nonEnumerableFallbackNames,
|
||||
PropertyNamePatternsMatcher includes) {
|
||||
PropertyNamePatternsMatcher includes, boolean resolvePlaceholders) {
|
||||
Assert.notNull(propertySources, "PropertySources must not be null");
|
||||
Assert.notNull(includes, "Includes must not be null");
|
||||
this.propertySources = propertySources;
|
||||
this.nonEnumerableFallbackNames = nonEnumerableFallbackNames;
|
||||
this.includes = includes;
|
||||
this.resolvePlaceholders = resolvePlaceholders;
|
||||
PropertySourcesPropertyResolver resolver = new PropertySourcesPropertyResolver(
|
||||
propertySources);
|
||||
for (PropertySource<?> source : propertySources) {
|
||||
|
|
@ -101,6 +106,16 @@ public class PropertySourcesPropertyValues implements PropertyValues {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag to indicate that placeholders should be replaced during binding. Default is
|
||||
* true.
|
||||
*
|
||||
* @param resolvePlaceholders flag value
|
||||
*/
|
||||
public void setResolvePlaceholders(boolean resolvePlaceholders) {
|
||||
this.resolvePlaceholders = resolvePlaceholders;
|
||||
}
|
||||
|
||||
private void processPropertySource(PropertySource<?> source,
|
||||
PropertySourcesPropertyResolver resolver) {
|
||||
if (source instanceof CompositePropertySource) {
|
||||
|
|
@ -138,12 +153,14 @@ public class PropertySourcesPropertyValues implements PropertyValues {
|
|||
private Object getEnumerableProperty(EnumerablePropertySource<?> source,
|
||||
PropertySourcesPropertyResolver resolver, String propertyName) {
|
||||
try {
|
||||
return resolver.getProperty(propertyName, Object.class);
|
||||
if (this.resolvePlaceholders) {
|
||||
return resolver.getProperty(propertyName, Object.class);
|
||||
}
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
// Probably could not resolve placeholders, ignore it here
|
||||
return source.getProperty(propertyName);
|
||||
}
|
||||
return source.getProperty(propertyName);
|
||||
}
|
||||
|
||||
private void processNonEnumerablePropertySource(PropertySource<?> source,
|
||||
|
|
|
|||
|
|
@ -105,6 +105,35 @@ public class PropertiesConfigurationFactoryTests {
|
|||
assertThat(foo.name).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void systemEnvironmentBindingWithDefaults() throws Exception {
|
||||
setupFactory();
|
||||
MutablePropertySources propertySources = new MutablePropertySources();
|
||||
MockPropertySource propertySource = new MockPropertySource(
|
||||
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
|
||||
propertySource.setProperty("name", "${foo.name:bar}");
|
||||
propertySources.addFirst(propertySource);
|
||||
this.factory.setPropertySources(propertySources);
|
||||
this.factory.afterPropertiesSet();
|
||||
Foo foo = this.factory.getObject();
|
||||
assertThat(foo.name).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void systemEnvironmentNoResolvePlaceholders() throws Exception {
|
||||
setupFactory();
|
||||
MutablePropertySources propertySources = new MutablePropertySources();
|
||||
MockPropertySource propertySource = new MockPropertySource(
|
||||
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
|
||||
propertySource.setProperty("name", "${foo.name:bar}");
|
||||
propertySources.addFirst(propertySource);
|
||||
this.factory.setPropertySources(propertySources);
|
||||
this.factory.setResolvePlaceholders(false);
|
||||
this.factory.afterPropertiesSet();
|
||||
Foo foo = this.factory.getObject();
|
||||
assertThat(foo.name).isEqualTo("${foo.name:bar}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void systemPropertyBindingFailuresAreIgnored() throws Exception {
|
||||
setupFactory();
|
||||
|
|
|
|||
Loading…
Reference in New Issue