CachedIntrospectionResults uses full WeakReference for any non-safe ClassLoader arrangement

Previously, CachedIntrospectionResults had three modes of caching, with the intermediate mode relying on WeakReferences in the JDK PropertyDescriptor implementation. Since the JDK is actually using SoftReferences there these days, losing information in case of a GC run with tough memory constraints, we want to allow for hard references in PropertyDescriptor objects and therefore use a full WeakReference for the CachedIntrospectionResults object itself.

Issue: SPR-10028
This commit is contained in:
Juergen Hoeller 2012-11-25 20:43:27 +01:00
parent df76f1497a
commit c368068c0c
1 changed files with 6 additions and 12 deletions

View File

@ -146,20 +146,16 @@ public class CachedIntrospectionResults {
results = (CachedIntrospectionResults) value;
}
if (results == null) {
// On JDK 1.5 and higher, it is almost always safe to cache the bean class...
// The sole exception is a custom BeanInfo class being provided in a non-safe ClassLoader.
boolean fullyCacheable =
ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
isClassLoaderAccepted(beanClass.getClassLoader());
if (fullyCacheable || !ClassUtils.isPresent(beanClass.getName() + "BeanInfo", beanClass.getClassLoader())) {
results = new CachedIntrospectionResults(beanClass, fullyCacheable);
if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
isClassLoaderAccepted(beanClass.getClassLoader())) {
results = new CachedIntrospectionResults(beanClass);
classCache.put(beanClass, results);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe");
}
results = new CachedIntrospectionResults(beanClass, true);
results = new CachedIntrospectionResults(beanClass);
classCache.put(beanClass, new WeakReference<CachedIntrospectionResults>(results));
}
}
@ -222,7 +218,7 @@ public class CachedIntrospectionResults {
* @param beanClass the bean class to analyze
* @throws BeansException in case of introspection failure
*/
private CachedIntrospectionResults(Class beanClass, boolean cacheFullMetadata) throws BeansException {
private CachedIntrospectionResults(Class beanClass) throws BeansException {
try {
if (logger.isTraceEnabled()) {
logger.trace("Getting BeanInfo for class [" + beanClass.getName() + "]");
@ -270,9 +266,7 @@ public class CachedIntrospectionResults {
(pd.getPropertyEditorClass() != null ?
"; editor [" + pd.getPropertyEditorClass().getName() + "]" : ""));
}
if (cacheFullMetadata) {
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
}
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
this.propertyDescriptorCache.put(pd.getName(), pd);
}
}