Use ConcurrentMap declarations when calling putIfAbsent (for compatibility with JDK 6 and 7)
Issue: SPR-12102
This commit is contained in:
parent
781a6d289e
commit
af6ef5f74c
|
|
@ -480,8 +480,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||||
}
|
}
|
||||||
TypeDescriptor td = cachedIntrospectionResults.getTypeDescriptor(pd);
|
TypeDescriptor td = cachedIntrospectionResults.getTypeDescriptor(pd);
|
||||||
if (td == null) {
|
if (td == null) {
|
||||||
td = new TypeDescriptor(property(pd));
|
td = cachedIntrospectionResults.addTypeDescriptor(pd, new TypeDescriptor(property(pd)));
|
||||||
cachedIntrospectionResults.addTypeDescriptor(pd, td);
|
|
||||||
}
|
}
|
||||||
return convertForProperty(propertyName, null, value, td);
|
return convertForProperty(propertyName, null, value, td);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
@ -112,14 +113,14 @@ public class CachedIntrospectionResults {
|
||||||
* Map keyed by Class containing CachedIntrospectionResults, strongly held.
|
* Map keyed by Class containing CachedIntrospectionResults, strongly held.
|
||||||
* This variant is being used for cache-safe bean classes.
|
* This variant is being used for cache-safe bean classes.
|
||||||
*/
|
*/
|
||||||
static final Map<Class<?>, CachedIntrospectionResults> strongClassCache =
|
static final ConcurrentMap<Class<?>, CachedIntrospectionResults> strongClassCache =
|
||||||
new ConcurrentHashMap<Class<?>, CachedIntrospectionResults>(64);
|
new ConcurrentHashMap<Class<?>, CachedIntrospectionResults>(64);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map keyed by Class containing CachedIntrospectionResults, softly held.
|
* Map keyed by Class containing CachedIntrospectionResults, softly held.
|
||||||
* This variant is being used for non-cache-safe bean classes.
|
* This variant is being used for non-cache-safe bean classes.
|
||||||
*/
|
*/
|
||||||
static final Map<Class<?>, CachedIntrospectionResults> softClassCache =
|
static final ConcurrentMap<Class<?>, CachedIntrospectionResults> softClassCache =
|
||||||
new ConcurrentReferenceHashMap<Class<?>, CachedIntrospectionResults>(64);
|
new ConcurrentReferenceHashMap<Class<?>, CachedIntrospectionResults>(64);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -186,17 +187,21 @@ public class CachedIntrospectionResults {
|
||||||
}
|
}
|
||||||
|
|
||||||
results = new CachedIntrospectionResults(beanClass);
|
results = new CachedIntrospectionResults(beanClass);
|
||||||
|
ConcurrentMap<Class<?>, CachedIntrospectionResults> classCacheToUse;
|
||||||
|
|
||||||
if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
|
if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
|
||||||
isClassLoaderAccepted(beanClass.getClassLoader())) {
|
isClassLoaderAccepted(beanClass.getClassLoader())) {
|
||||||
strongClassCache.putIfAbsent(beanClass, results);
|
classCacheToUse = strongClassCache;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe");
|
logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe");
|
||||||
}
|
}
|
||||||
softClassCache.putIfAbsent(beanClass, results);
|
classCacheToUse = softClassCache;
|
||||||
}
|
}
|
||||||
return results;
|
|
||||||
|
CachedIntrospectionResults existing = classCacheToUse.putIfAbsent(beanClass, results);
|
||||||
|
return (existing != null ? existing : results);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -246,7 +251,7 @@ public class CachedIntrospectionResults {
|
||||||
private final Map<String, PropertyDescriptor> propertyDescriptorCache;
|
private final Map<String, PropertyDescriptor> propertyDescriptorCache;
|
||||||
|
|
||||||
/** TypeDescriptor objects keyed by PropertyDescriptor */
|
/** TypeDescriptor objects keyed by PropertyDescriptor */
|
||||||
private final Map<PropertyDescriptor, TypeDescriptor> typeDescriptorCache;
|
private final ConcurrentMap<PropertyDescriptor, TypeDescriptor> typeDescriptorCache;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -295,7 +300,7 @@ public class CachedIntrospectionResults {
|
||||||
"; editor [" + pd.getPropertyEditorClass().getName() + "]" : ""));
|
"; editor [" + pd.getPropertyEditorClass().getName() + "]" : ""));
|
||||||
}
|
}
|
||||||
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
|
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
|
||||||
this.propertyDescriptorCache.putIfAbsent(pd.getName(), pd);
|
this.propertyDescriptorCache.put(pd.getName(), pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.typeDescriptorCache = new ConcurrentHashMap<PropertyDescriptor, TypeDescriptor>();
|
this.typeDescriptorCache = new ConcurrentHashMap<PropertyDescriptor, TypeDescriptor>();
|
||||||
|
|
@ -347,8 +352,9 @@ public class CachedIntrospectionResults {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTypeDescriptor(PropertyDescriptor pd, TypeDescriptor td) {
|
TypeDescriptor addTypeDescriptor(PropertyDescriptor pd, TypeDescriptor td) {
|
||||||
this.typeDescriptorCache.putIfAbsent(pd, td);
|
TypeDescriptor existing = this.typeDescriptorCache.putIfAbsent(pd, td);
|
||||||
|
return (existing != null ? existing : td);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDescriptor getTypeDescriptor(PropertyDescriptor pd) {
|
TypeDescriptor getTypeDescriptor(PropertyDescriptor pd) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue