diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java b/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java
index c3f287e2dbd..09e1941c93e 100644
--- a/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java
+++ b/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java
@@ -867,10 +867,17 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.object)) {
pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
if (pd == null || pd.getWriteMethod() == null) {
- PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass());
- throw new NotWritablePropertyException(
- getRootClass(), this.nestedPath + propertyName,
- matches.buildErrorMessage(), matches.getPossibleMatches());
+ if (pv.isOptional()) {
+ logger.debug("Ignoring optional value for property '" + actualName +
+ "' - property not found on bean class [" + getRootClass().getName() + "]");
+ return;
+ }
+ else {
+ PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass());
+ throw new NotWritablePropertyException(
+ getRootClass(), this.nestedPath + propertyName,
+ matches.buildErrorMessage(), matches.getPossibleMatches());
+ }
}
pv.getOriginalPropertyValue().resolvedDescriptor = pd;
}
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/PropertyValue.java b/org.springframework.beans/src/main/java/org/springframework/beans/PropertyValue.java
index 18bc05a2a1b..abc9c666629 100644
--- a/org.springframework.beans/src/main/java/org/springframework/beans/PropertyValue.java
+++ b/org.springframework.beans/src/main/java/org/springframework/beans/PropertyValue.java
@@ -47,6 +47,8 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
private Object source;
+ private boolean optional = false;
+
private boolean converted = false;
private Object convertedValue;
@@ -80,6 +82,7 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
this.name = original.getName();
this.value = original.getValue();
this.source = original.getSource();
+ this.optional = original.isOptional();
this.converted = original.converted;
this.convertedValue = original.convertedValue;
this.conversionNecessary = original.conversionNecessary;
@@ -99,6 +102,7 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
this.name = original.getName();
this.value = newValue;
this.source = original;
+ this.optional = original.isOptional();
this.conversionNecessary = original.conversionNecessary;
this.resolvedTokens = original.resolvedTokens;
this.resolvedDescriptor = original.resolvedDescriptor;
@@ -136,6 +140,14 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
return original;
}
+ public void setOptional(boolean optional) {
+ this.optional = optional;
+ }
+
+ public boolean isOptional() {
+ return this.optional;
+ }
+
/**
* Return whether this holder contains a converted value already (true),
* or whether the value still needs to be converted (false).
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java
index f937b646d3c..7d2125c66cb 100644
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java
+++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 the original author or authors.
+ * Copyright 2002-2009 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.
@@ -23,6 +23,7 @@ import java.util.Properties;
import java.util.Set;
import org.springframework.beans.BeansException;
+import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.BeanInitializationException;
/**
@@ -84,9 +85,9 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer {
/**
* Set whether to ignore invalid keys. Default is "false".
- *
If you ignore invalid keys, keys that do not follow the - * 'beanName.property' format will just be logged as warning. - * This allows to have arbitrary other keys in a properties file. + *
If you ignore invalid keys, keys that do not follow the 'beanName.property' format + * (or refer to invalid bean names or properties) will just be logged at debug level. + * This allows one to have arbitrary other keys in a properties file. */ public void setIgnoreInvalidKeys(boolean ignoreInvalidKeys) { this.ignoreInvalidKeys = ignoreInvalidKeys; @@ -138,13 +139,15 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer { * Apply the given property value to the corresponding bean. */ protected void applyPropertyValue( - ConfigurableListableBeanFactory factory, String beanName, String property, String value) { + ConfigurableListableBeanFactory factory, String beanName, String property, String value) { BeanDefinition bd = factory.getBeanDefinition(beanName); while (bd.getOriginatingBeanDefinition() != null) { bd = bd.getOriginatingBeanDefinition(); } - bd.getPropertyValues().addPropertyValue(property, value); + PropertyValue pv = new PropertyValue(property, value); + pv.setOptional(this.ignoreInvalidKeys); + bd.getPropertyValues().addPropertyValue(pv); } diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/config/PropertyResourceConfigurerTests.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/config/PropertyResourceConfigurerTests.java index a4370ed96d4..77ab1e039a6 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/config/PropertyResourceConfigurerTests.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/config/PropertyResourceConfigurerTests.java @@ -25,7 +25,6 @@ import java.util.prefs.Preferences; import static org.junit.Assert.*; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import test.beans.IndexedTestBean; import test.beans.TestBean; @@ -281,8 +280,11 @@ public final class PropertyResourceConfigurerTests { Properties props = new Properties(); props.setProperty("argh", "hgra"); props.setProperty("tb2.name", "test"); + props.setProperty("tb2.nam", "test"); + props.setProperty("tb3.name", "test"); poc.setProperties(props); poc.postProcessBeanFactory(factory); + assertEquals("test", factory.getBean("tb2", TestBean.class).getName()); } { PropertyOverrideConfigurer poc = new PropertyOverrideConfigurer(); @@ -294,7 +296,8 @@ public final class PropertyResourceConfigurerTests { poc.setOrder(0); // won't actually do anything since we're not processing through an app ctx try { poc.postProcessBeanFactory(factory); - } catch (BeanInitializationException ex) { + } + catch (BeanInitializationException ex) { // prove that the processor chokes on the invalid key assertTrue(ex.getMessage().toLowerCase().contains("argh")); }