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 44d076680d..f99f920b20 100644 --- a/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java +++ b/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java @@ -50,6 +50,18 @@ import org.springframework.util.StringUtils; * implements the factory design pattern, using a private constructor and * a static {@link #forClass(Class)} factory method to obtain instances. * + *
Note that for caching to work effectively, some preconditions need to be met: + * Prefer an arrangement where the Spring jars live in the same ClassLoader as the + * application classes, which allows for clean caching along with the application's + * lifecycle in any case. For a web application, consider declaring a local + * {@link org.springframework.web.util.IntrospectorCleanupListener} in {@code web.xml} + * in case of a multi-ClassLoader layout, which will allow for effective caching as well. + * + *
In case of a non-clean ClassLoader arrangement without a cleanup listener having + * been set up, this class will fall back to a weak-reference-based caching model that + * recreates much-requested entries every time the garbage collector removed them. In + * such a scenario, consider the {@link #IGNORE_BEANINFO_PROPERTY_NAME} system property. + * * @author Rod Johnson * @author Juergen Hoeller * @since 05 May 2001 @@ -59,11 +71,33 @@ import org.springframework.util.StringUtils; */ public class CachedIntrospectionResults { + /** + * System property that instructs Spring to use the {@link Introspector#IGNORE_ALL_BEANINFO} + * mode when calling the JavaBeans {@link Introspector}: "spring.beaninfo.ignore", with a + * value of "true" skipping the search for {@code BeanInfo} classes (typically for scenarios + * where no such classes are being defined for beans in the application in the first place). + *
Default is "false", considering all {@code BeanInfo} metadata classes, like for + * standard {@link Introspector#getBeanInfo(Class)} calls. Consider switching this flag to + * "true" if you experience repeated ClassLoader access for non-existing {@code BeanInfo} + * classes, in case such access is expensive on startup or on lazy loading. + *
Note that such an effect may also indicate a scenario where caching doesn't work
+ * effectively: Prefer an arrangement where the Spring jars live in the same ClassLoader
+ * as the application classes, which allows for clean caching along with the application's
+ * lifecycle in any case. For a web application, consider declaring a local
+ * {@link org.springframework.web.util.IntrospectorCleanupListener} in {@code web.xml}
+ * in case of a multi-ClassLoader layout, which will allow for effective caching as well.
+ * @see Introspector#getBeanInfo(Class, int)
+ */
+ public static final String IGNORE_BEANINFO_PROPERTY_NAME = "spring.beaninfo.ignore";
+
+
private static final Log logger = LogFactory.getLog(CachedIntrospectionResults.class);
+ private static final boolean shouldIntrospectorIgnoreBeaninfoClasses;
+
/** Stores the BeanInfoFactory instances */
- private static List