Skip to content

Commit af6ef5f

Browse files
committed
Use ConcurrentMap declarations when calling putIfAbsent (for compatibility with JDK 6 and 7)
Issue: SPR-12102
1 parent 781a6d2 commit af6ef5f

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,7 @@ public Object convertForProperty(Object value, String propertyName) throws TypeM
480480
}
481481
TypeDescriptor td = cachedIntrospectionResults.getTypeDescriptor(pd);
482482
if (td == null) {
483-
td = new TypeDescriptor(property(pd));
484-
cachedIntrospectionResults.addTypeDescriptor(pd, td);
483+
td = cachedIntrospectionResults.addTypeDescriptor(pd, new TypeDescriptor(property(pd)));
485484
}
486485
return convertForProperty(propertyName, null, value, td);
487486
}

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.Map;
2828
import java.util.Set;
2929
import java.util.concurrent.ConcurrentHashMap;
30+
import java.util.concurrent.ConcurrentMap;
3031

3132
import org.apache.commons.logging.Log;
3233
import org.apache.commons.logging.LogFactory;
@@ -112,14 +113,14 @@ public class CachedIntrospectionResults {
112113
* Map keyed by Class containing CachedIntrospectionResults, strongly held.
113114
* This variant is being used for cache-safe bean classes.
114115
*/
115-
static final Map<Class<?>, CachedIntrospectionResults> strongClassCache =
116+
static final ConcurrentMap<Class<?>, CachedIntrospectionResults> strongClassCache =
116117
new ConcurrentHashMap<Class<?>, CachedIntrospectionResults>(64);
117118

118119
/**
119120
* Map keyed by Class containing CachedIntrospectionResults, softly held.
120121
* This variant is being used for non-cache-safe bean classes.
121122
*/
122-
static final Map<Class<?>, CachedIntrospectionResults> softClassCache =
123+
static final ConcurrentMap<Class<?>, CachedIntrospectionResults> softClassCache =
123124
new ConcurrentReferenceHashMap<Class<?>, CachedIntrospectionResults>(64);
124125

125126

@@ -186,17 +187,21 @@ static CachedIntrospectionResults forClass(Class<?> beanClass) throws BeansExcep
186187
}
187188

188189
results = new CachedIntrospectionResults(beanClass);
190+
ConcurrentMap<Class<?>, CachedIntrospectionResults> classCacheToUse;
191+
189192
if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
190193
isClassLoaderAccepted(beanClass.getClassLoader())) {
191-
strongClassCache.putIfAbsent(beanClass, results);
194+
classCacheToUse = strongClassCache;
192195
}
193196
else {
194197
if (logger.isDebugEnabled()) {
195198
logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe");
196199
}
197-
softClassCache.putIfAbsent(beanClass, results);
200+
classCacheToUse = softClassCache;
198201
}
199-
return results;
202+
203+
CachedIntrospectionResults existing = classCacheToUse.putIfAbsent(beanClass, results);
204+
return (existing != null ? existing : results);
200205
}
201206

202207
/**
@@ -246,7 +251,7 @@ private static boolean isUnderneathClassLoader(ClassLoader candidate, ClassLoade
246251
private final Map<String, PropertyDescriptor> propertyDescriptorCache;
247252

248253
/** TypeDescriptor objects keyed by PropertyDescriptor */
249-
private final Map<PropertyDescriptor, TypeDescriptor> typeDescriptorCache;
254+
private final ConcurrentMap<PropertyDescriptor, TypeDescriptor> typeDescriptorCache;
250255

251256

252257
/**
@@ -295,7 +300,7 @@ private CachedIntrospectionResults(Class<?> beanClass) throws BeansException {
295300
"; editor [" + pd.getPropertyEditorClass().getName() + "]" : ""));
296301
}
297302
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
298-
this.propertyDescriptorCache.putIfAbsent(pd.getName(), pd);
303+
this.propertyDescriptorCache.put(pd.getName(), pd);
299304
}
300305

301306
this.typeDescriptorCache = new ConcurrentHashMap<PropertyDescriptor, TypeDescriptor>();
@@ -347,8 +352,9 @@ private PropertyDescriptor buildGenericTypeAwarePropertyDescriptor(Class<?> bean
347352
}
348353
}
349354

350-
void addTypeDescriptor(PropertyDescriptor pd, TypeDescriptor td) {
351-
this.typeDescriptorCache.putIfAbsent(pd, td);
355+
TypeDescriptor addTypeDescriptor(PropertyDescriptor pd, TypeDescriptor td) {
356+
TypeDescriptor existing = this.typeDescriptorCache.putIfAbsent(pd, td);
357+
return (existing != null ? existing : td);
352358
}
353359

354360
TypeDescriptor getTypeDescriptor(PropertyDescriptor pd) {

0 commit comments

Comments
 (0)