java.beans.PropertyDescriptor
information for a Java class. Not intended for direct use by application code.
Necessary for Spring's own caching of bean descriptors within the application
ClassLoader, rather than relying on the JDK's system-wide BeanInfo
cache (in order to avoid leaks on individual application shutdown in a shared JVM).
Information is cached statically, so we don't need to create new
objects of this class for every JavaBean we manipulate. Hence, this class
implements the factory design pattern, using a private constructor and
a static 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.
As of 6.0, Spring's default introspection discovers basic JavaBeans properties
through an efficient method reflection pass. For full JavaBeans introspection
including indexed properties and all JDK-supported customizers, configure a
META-INF/spring.factories file with the following content:
org.springframework.beans.BeanInfoFactory=org.springframework.beans.StandardBeanInfoFactory
For Spring 5.3 compatible extended introspection including non-void setter methods:
org.springframework.beans.BeanInfoFactory=org.springframework.beans.ExtendedBeanInfoFactory
acceptClassLoader(ClassLoader), clearClassLoader(ClassLoader), forClass(Class)
| Modifier and Type | Field and Description |
|---|---|
| pack-priv static final Set | acceptedClassLoaders
Set of ClassLoaders that this CachedIntrospectionResults class will always accept classes from, even if the classes do not qualify as cache-safe. |
| private final BeanInfo | beanInfo
The BeanInfo object for the introspected bean class. |
| private static final List | |
| private static final Log | |
| private final Map | propertyDescriptors
PropertyDescriptor objects keyed by property name String. |
| private static final SimpleBeanInfoFactory | |
| pack-priv static final ConcurrentMap | softClassCache
Map keyed by Class containing CachedIntrospectionResults, softly held. |
| pack-priv static final ConcurrentMap | strongClassCache
Map keyed by Class containing CachedIntrospectionResults, strongly held. |
| Access | Constructor and Description |
|---|---|
| private | CachedIntrospectionResults(Class<?>
the bean class to analyze beanClass)Create a new CachedIntrospectionResults instance for the given class. |
| Modifier and Type | Method and Description |
|---|---|
| public static void | acceptClassLoader(ClassLoader
the ClassLoader to accept classLoader)Accept the given ClassLoader as cache-safe, even if its classes would not qualify as cache-safe in this CachedIntrospectionResults class. |
| private PropertyDescriptor | |
| public static void | clearClassLoader(ClassLoader
the ClassLoader to clear the cache for classLoader)Clear the introspection cache for the given ClassLoader, removing the introspection results for all classes underneath that ClassLoader, and removing the ClassLoader (and its children) from the acceptance list. |
| pack-priv static CachedIntrospectionResults | |
| pack-priv Class | |
| private static BeanInfo | Returns: the resultingBeanInfo descriptor (never null)the target class to introspect beanClass)Retrieve a |
| pack-priv BeanInfo | |
| pack-priv PropertyDescriptor | |
| pack-priv PropertyDescriptor[] | |
| private void | |
| private void | |
| private static boolean | Returns: whether the given ClassLoader is acceptedthe ClassLoader to check classLoader)Check whether this CachedIntrospectionResults class is configured to accept the given ClassLoader. |
| private boolean | |
| private boolean | |
| private static boolean | isUnderneathClassLoader(ClassLoader
the candidate ClassLoader to check candidate, ClassLoader the parent ClassLoader to check for parent)Check whether the given ClassLoader is underneath the given parent, that is, whether the parent is within the candidate's hierarchy. |
| acceptedClassLoaders | back to summary |
|---|---|
| pack-priv static final Set<ClassLoader> acceptedClassLoaders Set of ClassLoaders that this CachedIntrospectionResults class will always accept classes from, even if the classes do not qualify as cache-safe. | |
| beanInfo | back to summary |
|---|---|
| private final BeanInfo beanInfo The BeanInfo object for the introspected bean class. | |
| beanInfoFactories | back to summary |
|---|---|
| private static final List<BeanInfoFactory> beanInfoFactories | |
| logger | back to summary |
|---|---|
| private static final Log logger | |
| propertyDescriptors | back to summary |
|---|---|
| private final Map<String, PropertyDescriptor> propertyDescriptors PropertyDescriptor objects keyed by property name String. | |
| simpleBeanInfoFactory | back to summary |
|---|---|
| private static final SimpleBeanInfoFactory simpleBeanInfoFactory | |
| softClassCache | back to summary |
|---|---|
| pack-priv static final ConcurrentMap<Class<?>, CachedIntrospectionResults> softClassCache Map keyed by Class containing CachedIntrospectionResults, softly held. This variant is being used for non-cache-safe bean classes. | |
| strongClassCache | back to summary |
|---|---|
| pack-priv static final ConcurrentMap<Class<?>, CachedIntrospectionResults> strongClassCache Map keyed by Class containing CachedIntrospectionResults, strongly held. This variant is being used for cache-safe bean classes. | |
| CachedIntrospectionResults | back to summary |
|---|---|
| private CachedIntrospectionResults(Class<?> beanClass) throws BeansException Create a new CachedIntrospectionResults instance for the given class.
| |
| acceptClassLoader | back to summary |
|---|---|
| public static void acceptClassLoader(ClassLoader classLoader) Accept the given ClassLoader as cache-safe, even if its classes would not qualify as cache-safe in this CachedIntrospectionResults class. This configuration method is only relevant in scenarios where the Spring classes reside in a 'common' ClassLoader (e.g. the system ClassLoader) whose lifecycle is not coupled to the application. In such a scenario, CachedIntrospectionResults would by default not cache any of the application's classes, since they would create a leak in the common ClassLoader. Any
| |
| buildGenericTypeAwarePropertyDescriptor | back to summary |
|---|---|
| private PropertyDescriptor buildGenericTypeAwarePropertyDescriptor(Class<?> beanClass, PropertyDescriptor pd) | |
| clearClassLoader | back to summary |
|---|---|
| public static void clearClassLoader(ClassLoader classLoader) Clear the introspection cache for the given ClassLoader, removing the introspection results for all classes underneath that ClassLoader, and removing the ClassLoader (and its children) from the acceptance list.
| |
| forClass | back to summary |
|---|---|
| pack-priv static CachedIntrospectionResults forClass(Class<?> beanClass) throws BeansException Create CachedIntrospectionResults for the given bean class.
| |
| getBeanClass | back to summary |
|---|---|
| pack-priv Class | |
| getBeanInfo | back to summary |
|---|---|
| private static BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException Retrieve a
| |
| getBeanInfo | back to summary |
|---|---|
| pack-priv BeanInfo getBeanInfo() | |
| getPropertyDescriptor | back to summary |
|---|---|
pack-priv PropertyDescriptor getPropertyDescriptor(String name)
| |
| getPropertyDescriptors | back to summary |
|---|---|
| pack-priv PropertyDescriptor[] getPropertyDescriptors() | |
| introspectInterfaces | back to summary |
|---|---|
| private void introspectInterfaces(Class<?> beanClass, Class<?> currClass, Set<String> readMethodNames) throws IntrospectionException | |
| introspectPlainAccessors | back to summary |
|---|---|
| private void introspectPlainAccessors(Class<?> beanClass, Set<String> readMethodNames) throws IntrospectionException | |
| isClassLoaderAccepted | back to summary |
|---|---|
| private static boolean isClassLoaderAccepted(ClassLoader classLoader) Check whether this CachedIntrospectionResults class is configured to accept the given ClassLoader.
| |
| isInvalidReadOnlyPropertyType | back to summary |
|---|---|
| private boolean isInvalidReadOnlyPropertyType(Class<?> returnType, Class<?> beanClass) | |
| isPlainAccessor | back to summary |
|---|---|
| private boolean isPlainAccessor(Method method) | |
| isUnderneathClassLoader | back to summary |
|---|---|
| private static boolean isUnderneathClassLoader(ClassLoader candidate, ClassLoader parent) Check whether the given ClassLoader is underneath the given parent, that is, whether the parent is within the candidate's hierarchy.
| |