|
27 | 27 | import java.util.Map; |
28 | 28 | import java.util.Set; |
29 | 29 | import java.util.concurrent.ConcurrentHashMap; |
| 30 | +import java.util.concurrent.ConcurrentMap; |
30 | 31 |
|
31 | 32 | import org.apache.commons.logging.Log; |
32 | 33 | import org.apache.commons.logging.LogFactory; |
@@ -112,14 +113,14 @@ public class CachedIntrospectionResults { |
112 | 113 | * Map keyed by Class containing CachedIntrospectionResults, strongly held. |
113 | 114 | * This variant is being used for cache-safe bean classes. |
114 | 115 | */ |
115 | | - static final Map<Class<?>, CachedIntrospectionResults> strongClassCache = |
| 116 | + static final ConcurrentMap<Class<?>, CachedIntrospectionResults> strongClassCache = |
116 | 117 | new ConcurrentHashMap<Class<?>, CachedIntrospectionResults>(64); |
117 | 118 |
|
118 | 119 | /** |
119 | 120 | * Map keyed by Class containing CachedIntrospectionResults, softly held. |
120 | 121 | * This variant is being used for non-cache-safe bean classes. |
121 | 122 | */ |
122 | | - static final Map<Class<?>, CachedIntrospectionResults> softClassCache = |
| 123 | + static final ConcurrentMap<Class<?>, CachedIntrospectionResults> softClassCache = |
123 | 124 | new ConcurrentReferenceHashMap<Class<?>, CachedIntrospectionResults>(64); |
124 | 125 |
|
125 | 126 |
|
@@ -186,17 +187,21 @@ static CachedIntrospectionResults forClass(Class<?> beanClass) throws BeansExcep |
186 | 187 | } |
187 | 188 |
|
188 | 189 | results = new CachedIntrospectionResults(beanClass); |
| 190 | + ConcurrentMap<Class<?>, CachedIntrospectionResults> classCacheToUse; |
| 191 | + |
189 | 192 | if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) || |
190 | 193 | isClassLoaderAccepted(beanClass.getClassLoader())) { |
191 | | - strongClassCache.putIfAbsent(beanClass, results); |
| 194 | + classCacheToUse = strongClassCache; |
192 | 195 | } |
193 | 196 | else { |
194 | 197 | if (logger.isDebugEnabled()) { |
195 | 198 | logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe"); |
196 | 199 | } |
197 | | - softClassCache.putIfAbsent(beanClass, results); |
| 200 | + classCacheToUse = softClassCache; |
198 | 201 | } |
199 | | - return results; |
| 202 | + |
| 203 | + CachedIntrospectionResults existing = classCacheToUse.putIfAbsent(beanClass, results); |
| 204 | + return (existing != null ? existing : results); |
200 | 205 | } |
201 | 206 |
|
202 | 207 | /** |
@@ -246,7 +251,7 @@ private static boolean isUnderneathClassLoader(ClassLoader candidate, ClassLoade |
246 | 251 | private final Map<String, PropertyDescriptor> propertyDescriptorCache; |
247 | 252 |
|
248 | 253 | /** TypeDescriptor objects keyed by PropertyDescriptor */ |
249 | | - private final Map<PropertyDescriptor, TypeDescriptor> typeDescriptorCache; |
| 254 | + private final ConcurrentMap<PropertyDescriptor, TypeDescriptor> typeDescriptorCache; |
250 | 255 |
|
251 | 256 |
|
252 | 257 | /** |
@@ -295,7 +300,7 @@ private CachedIntrospectionResults(Class<?> beanClass) throws BeansException { |
295 | 300 | "; editor [" + pd.getPropertyEditorClass().getName() + "]" : "")); |
296 | 301 | } |
297 | 302 | pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd); |
298 | | - this.propertyDescriptorCache.putIfAbsent(pd.getName(), pd); |
| 303 | + this.propertyDescriptorCache.put(pd.getName(), pd); |
299 | 304 | } |
300 | 305 |
|
301 | 306 | this.typeDescriptorCache = new ConcurrentHashMap<PropertyDescriptor, TypeDescriptor>(); |
@@ -347,8 +352,9 @@ private PropertyDescriptor buildGenericTypeAwarePropertyDescriptor(Class<?> bean |
347 | 352 | } |
348 | 353 | } |
349 | 354 |
|
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); |
352 | 358 | } |
353 | 359 |
|
354 | 360 | TypeDescriptor getTypeDescriptor(PropertyDescriptor pd) { |
|
0 commit comments