Skip to content

Commit ad492e9

Browse files
committed
PropertyOverrideConfigurer's "ignoreInvalidKeys" ignores invalid property names as well (SPR-5792)
1 parent 557dd1f commit ad492e9

File tree

4 files changed

+37
-12
lines changed

4 files changed

+37
-12
lines changed

org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -867,10 +867,17 @@ else if (propValue instanceof Map) {
867867
if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.object)) {
868868
pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
869869
if (pd == null || pd.getWriteMethod() == null) {
870-
PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass());
871-
throw new NotWritablePropertyException(
872-
getRootClass(), this.nestedPath + propertyName,
873-
matches.buildErrorMessage(), matches.getPossibleMatches());
870+
if (pv.isOptional()) {
871+
logger.debug("Ignoring optional value for property '" + actualName +
872+
"' - property not found on bean class [" + getRootClass().getName() + "]");
873+
return;
874+
}
875+
else {
876+
PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass());
877+
throw new NotWritablePropertyException(
878+
getRootClass(), this.nestedPath + propertyName,
879+
matches.buildErrorMessage(), matches.getPossibleMatches());
880+
}
874881
}
875882
pv.getOriginalPropertyValue().resolvedDescriptor = pd;
876883
}

org.springframework.beans/src/main/java/org/springframework/beans/PropertyValue.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
4747

4848
private Object source;
4949

50+
private boolean optional = false;
51+
5052
private boolean converted = false;
5153

5254
private Object convertedValue;
@@ -80,6 +82,7 @@ public PropertyValue(PropertyValue original) {
8082
this.name = original.getName();
8183
this.value = original.getValue();
8284
this.source = original.getSource();
85+
this.optional = original.isOptional();
8386
this.converted = original.converted;
8487
this.convertedValue = original.convertedValue;
8588
this.conversionNecessary = original.conversionNecessary;
@@ -99,6 +102,7 @@ public PropertyValue(PropertyValue original, Object newValue) {
99102
this.name = original.getName();
100103
this.value = newValue;
101104
this.source = original;
105+
this.optional = original.isOptional();
102106
this.conversionNecessary = original.conversionNecessary;
103107
this.resolvedTokens = original.resolvedTokens;
104108
this.resolvedDescriptor = original.resolvedDescriptor;
@@ -136,6 +140,14 @@ public PropertyValue getOriginalPropertyValue() {
136140
return original;
137141
}
138142

143+
public void setOptional(boolean optional) {
144+
this.optional = optional;
145+
}
146+
147+
public boolean isOptional() {
148+
return this.optional;
149+
}
150+
139151
/**
140152
* Return whether this holder contains a converted value already (<code>true</code>),
141153
* or whether the value still needs to be converted (<code>false</code>).

org.springframework.beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2008 the original author or authors.
2+
* Copyright 2002-2009 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
2323
import java.util.Set;
2424

2525
import org.springframework.beans.BeansException;
26+
import org.springframework.beans.PropertyValue;
2627
import org.springframework.beans.factory.BeanInitializationException;
2728

2829
/**
@@ -84,9 +85,9 @@ public void setBeanNameSeparator(String beanNameSeparator) {
8485

8586
/**
8687
* Set whether to ignore invalid keys. Default is "false".
87-
* <p>If you ignore invalid keys, keys that do not follow the
88-
* 'beanName.property' format will just be logged as warning.
89-
* This allows to have arbitrary other keys in a properties file.
88+
* <p>If you ignore invalid keys, keys that do not follow the 'beanName.property' format
89+
* (or refer to invalid bean names or properties) will just be logged at debug level.
90+
* This allows one to have arbitrary other keys in a properties file.
9091
*/
9192
public void setIgnoreInvalidKeys(boolean ignoreInvalidKeys) {
9293
this.ignoreInvalidKeys = ignoreInvalidKeys;
@@ -138,13 +139,15 @@ protected void processKey(ConfigurableListableBeanFactory factory, String key, S
138139
* Apply the given property value to the corresponding bean.
139140
*/
140141
protected void applyPropertyValue(
141-
ConfigurableListableBeanFactory factory, String beanName, String property, String value) {
142+
ConfigurableListableBeanFactory factory, String beanName, String property, String value) {
142143

143144
BeanDefinition bd = factory.getBeanDefinition(beanName);
144145
while (bd.getOriginatingBeanDefinition() != null) {
145146
bd = bd.getOriginatingBeanDefinition();
146147
}
147-
bd.getPropertyValues().addPropertyValue(property, value);
148+
PropertyValue pv = new PropertyValue(property, value);
149+
pv.setOptional(this.ignoreInvalidKeys);
150+
bd.getPropertyValues().addPropertyValue(pv);
148151
}
149152

150153

org.springframework.beans/src/test/java/org/springframework/beans/factory/config/PropertyResourceConfigurerTests.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
import static org.junit.Assert.*;
2727
import org.junit.Before;
28-
import org.junit.Ignore;
2928
import org.junit.Test;
3029
import test.beans.IndexedTestBean;
3130
import test.beans.TestBean;
@@ -281,8 +280,11 @@ public void testPropertyOverrideConfigurerWithInvalidKey() {
281280
Properties props = new Properties();
282281
props.setProperty("argh", "hgra");
283282
props.setProperty("tb2.name", "test");
283+
props.setProperty("tb2.nam", "test");
284+
props.setProperty("tb3.name", "test");
284285
poc.setProperties(props);
285286
poc.postProcessBeanFactory(factory);
287+
assertEquals("test", factory.getBean("tb2", TestBean.class).getName());
286288
}
287289
{
288290
PropertyOverrideConfigurer poc = new PropertyOverrideConfigurer();
@@ -294,7 +296,8 @@ public void testPropertyOverrideConfigurerWithInvalidKey() {
294296
poc.setOrder(0); // won't actually do anything since we're not processing through an app ctx
295297
try {
296298
poc.postProcessBeanFactory(factory);
297-
} catch (BeanInitializationException ex) {
299+
}
300+
catch (BeanInitializationException ex) {
298301
// prove that the processor chokes on the invalid key
299302
assertTrue(ex.getMessage().toLowerCase().contains("argh"));
300303
}

0 commit comments

Comments
 (0)