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`.
This commit is contained in:
parent
fd1b48139f
commit
c2b56c07e5
|
|
@ -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
|
|||
}
|
||||
}
|
||||
}
|
||||
valueToApply = convertForProperty(propertyName, oldValue, originalValue, pd);
|
||||
valueToApply = convertForProperty(propertyName, oldValue, originalValue, pd, new TypeDescriptor(property(pd)));
|
||||
}
|
||||
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
|||
|
||||
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 {
|
|||
/** 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 {
|
|||
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 {
|
|||
}
|
||||
}
|
||||
|
||||
TypeDescriptor getTypeDescriptor(PropertyDescriptor pd) {
|
||||
return this.typeDescriptorCache.get(pd);
|
||||
}
|
||||
|
||||
void putTypeDescriptor(PropertyDescriptor pd, TypeDescriptor td) {
|
||||
this.typeDescriptorCache.put(pd, td);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue