Browse Source

Cache property TypeDescriptors

Attempt to improve performance by caching TypeDescriptors against bean
PropertyDescriptors in CachedIntrospectionResults.

This change is an attempt to fix the failing performance test case
`testPrototypeCreationWithOverriddenResourcePropertiesIsFastEnough` in
`AnnotationProcessorPerformanceTests`.
pull/423/head
Phillip Webb 11 years ago
parent
commit
c2b56c07e5
  1. 17
      spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java
  2. 15
      spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java

17
spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java

@ -490,18 +490,23 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra @@ -490,18 +490,23 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
* @throws TypeMismatchException if type conversion failed
*/
public Object convertForProperty(Object value, String propertyName) throws TypeMismatchException {
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(propertyName);
CachedIntrospectionResults cachedIntrospectionResults = getCachedIntrospectionResults();
PropertyDescriptor pd = cachedIntrospectionResults.getPropertyDescriptor(propertyName);
TypeDescriptor td = cachedIntrospectionResults.getTypeDescriptor(pd);
if (pd == null) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"No property '" + propertyName + "' found");
}
return convertForProperty(propertyName, null, value, pd);
if (td == null) {
td = new TypeDescriptor(property(pd));
cachedIntrospectionResults.putTypeDescriptor(pd, td);
}
return convertForProperty(propertyName, null, value, pd, td);
}
private Object convertForProperty(String propertyName, Object oldValue, Object newValue, PropertyDescriptor pd)
private Object convertForProperty(String propertyName, Object oldValue, Object newValue, PropertyDescriptor pd, TypeDescriptor td)
throws TypeMismatchException {
return convertIfNecessary(propertyName, oldValue, newValue, pd.getPropertyType(), new TypeDescriptor(property(pd)));
return convertIfNecessary(propertyName, oldValue, newValue, pd.getPropertyType(), td);
}
private Property property(PropertyDescriptor pd) {
@ -1107,7 +1112,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra @@ -1107,7 +1112,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
}
}
valueToApply = convertForProperty(propertyName, oldValue, originalValue, pd);
valueToApply = convertForProperty(propertyName, oldValue, originalValue, pd, new TypeDescriptor(property(pd)));
}
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
}

15
spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java

@ -22,6 +22,7 @@ import java.beans.Introspector; @@ -22,6 +22,7 @@ import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
@ -32,6 +33,7 @@ import java.util.WeakHashMap; @@ -32,6 +33,7 @@ import java.util.WeakHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@ -216,6 +218,9 @@ public class CachedIntrospectionResults { @@ -216,6 +218,9 @@ public class CachedIntrospectionResults {
/** PropertyDescriptor objects keyed by property name String */
private final Map<String, PropertyDescriptor> propertyDescriptorCache;
/** TypeDescriptor objects keyed by PropertyDescriptor */
private final Map<PropertyDescriptor, TypeDescriptor> typeDescriptorCache;
/**
* Create a new CachedIntrospectionResults instance for the given class.
@ -273,6 +278,8 @@ public class CachedIntrospectionResults { @@ -273,6 +278,8 @@ public class CachedIntrospectionResults {
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
this.propertyDescriptorCache.put(pd.getName(), pd);
}
this.typeDescriptorCache = new HashMap<PropertyDescriptor, TypeDescriptor>();
}
catch (IntrospectionException ex) {
throw new FatalBeanException("Failed to obtain BeanInfo for class [" + beanClass.getName() + "]", ex);
@ -321,4 +328,12 @@ public class CachedIntrospectionResults { @@ -321,4 +328,12 @@ public class CachedIntrospectionResults {
}
}
TypeDescriptor getTypeDescriptor(PropertyDescriptor pd) {
return this.typeDescriptorCache.get(pd);
}
void putTypeDescriptor(PropertyDescriptor pd, TypeDescriptor td) {
this.typeDescriptorCache.put(pd, td);
}
}

Loading…
Cancel
Save