From c368068c0c17b77377ee2dc2314a10541c41daab Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sun, 25 Nov 2012 20:43:27 +0100 Subject: [PATCH] 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 --- .../beans/CachedIntrospectionResults.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java b/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java index 92bca358b86..91ef2ac914a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java +++ b/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java @@ -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(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); } }