|
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