Package: org.grails.beans.support

## [Java] Class CachedIntrospectionResults

- org.grails.beans.support.CachedIntrospectionResults

- Internal class that caches JavaBeans java.beans.PropertyDescriptor information for a Java class. Not intended for direct use by application code.

  Necessary for own caching of descriptors within the application's ClassLoader, rather than rely on the JDK's system-wide BeanInfo cache (in order to avoid leaks on ClassLoader shutdown).

  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. For a web application, consider declaring a local org.springframework.web.util.IntrospectorCleanupListener in `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 IGNORE_BEANINFO_PROPERTY_NAME system property.

  deprecated:
    Will be removed in a future version of Grails
  Authors:
    Rod Johnson
    Juergen Hoeller
  See Also:
    acceptClassLoader(ClassLoader)
    clearClassLoader(ClassLoader)
    forClass(Class)
  Since:
    05 May 2001

- - ### Field Summary

    Fields
    Modifiers | Name | Description
    --- | --- | ---
    `static java.lang.String` | `IGNORE_BEANINFO_PROPERTY_NAME` | System property that instructs Spring to use the java.beans.Introspector#IGNORE_ALL_BEANINFO mode when calling the JavaBeans java.beans.Introspector: "spring.beaninfo.ignore", with a value of "true" skipping the search for `BeanInfo` classes (typically for scenarios where no such classes are being defined for beans in the application in the first place).

  - ### Methods Summary

    Methods
    Type | Name and description
    --- | ---
    `static void` | `acceptClassLoader(java.lang.ClassLoader classLoader)` Accept the given ClassLoader as cache-safe, even if its classes would not qualify as cache-safe in this CachedIntrospectionResults class.
    `org.springframework.core.convert.TypeDescriptor` | `addTypeDescriptor(java.beans.PropertyDescriptor pd, org.springframework.core.convert.TypeDescriptor td)`
    `static void` | `clearClassLoader(java.lang.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.
    `static boolean` | `equals(java.beans.PropertyDescriptor pd, java.beans.PropertyDescriptor otherPd)` Compare the given `PropertyDescriptors` and return `true` if they are equivalent, i.e. their read method, write method, property type, property editor and flags are equivalent.
    `static CachedIntrospectionResults` | `forClass(java.lang.Class<?> beanClass)` Create CachedIntrospectionResults for the given bean class.
    `java.lang.Class<?>` | `getBeanClass()`
    `java.beans.BeanInfo` | `getBeanInfo()`
    `java.beans.PropertyDescriptor` | `getPropertyDescriptor(java.lang.String name)`
    `java.beans.PropertyDescriptor[]` | `getPropertyDescriptors()`
    `org.springframework.core.convert.TypeDescriptor` | `getTypeDescriptor(java.beans.PropertyDescriptor pd)`

  - ### Inherited Methods Summary

    Inherited Methods
    Methods inherited from class | Name
    --- | ---
    `class java.lang.Object` | `java.lang.Object#wait(long, int), java.lang.Object#wait(long), java.lang.Object#wait(), java.lang.Object#equals(java.lang.Object), java.lang.Object#toString(), java.lang.Object#hashCode(), java.lang.Object#getClass(), java.lang.Object#notify(), java.lang.Object#notifyAll()`

- - ### Field Detail

    - #### public static final java.lang.String IGNORE_BEANINFO_PROPERTY_NAME

      System property that instructs Spring to use the java.beans.Introspector#IGNORE_ALL_BEANINFO mode when calling the JavaBeans java.beans.Introspector: "spring.beaninfo.ignore", with a value of "true" skipping the search for `BeanInfo` classes (typically for scenarios where no such classes are being defined for beans in the application in the first place).

      The default is "false", considering all `BeanInfo` metadata classes, like for standard java.beans.Introspector#getBeanInfo(Class) calls. Consider switching this flag to "true" if you experience repeated ClassLoader access for non-existing `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 org.springframework.web.util.IntrospectorCleanupListener in `web.xml` in case of a multi-ClassLoader layout, which will allow for effective caching as well.

      See Also:
        java.beans.Introspector#getBeanInfo(Class, int)

  - ### Method Detail

    - #### public static void acceptClassLoader(java.lang.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 `acceptClassLoader` call at application startup should be paired with a clearClassLoader call at application shutdown.

      Parameters:
        `classLoader` - the ClassLoader to accept

    - #### public org.springframework.core.convert.TypeDescriptor addTypeDescriptor(java.beans.PropertyDescriptor pd, org.springframework.core.convert.TypeDescriptor td)

    - #### public static void clearClassLoader(java.lang.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.

      Parameters:
        `classLoader` - the ClassLoader to clear the cache for

    - #### public static boolean equals(java.beans.PropertyDescriptor pd, java.beans.PropertyDescriptor otherPd)

      Compare the given `PropertyDescriptors` and return `true` if they are equivalent, i.e. their read method, write method, property type, property editor and flags are equivalent.

      See Also:
        java.beans.PropertyDescriptor#equals(Object)

    - #### @java.lang.SuppressWarnings("unchecked") public static CachedIntrospectionResults forClass(java.lang.Class<?> beanClass)

      Create CachedIntrospectionResults for the given bean class.

      throws:
        org.springframework.beans.BeansException in case of introspection failure
      Parameters:
        `beanClass` - the bean class to analyze
      Returns:
        the corresponding CachedIntrospectionResults

    - #### public java.lang.Class<?> getBeanClass()

    - #### public java.beans.BeanInfo getBeanInfo()

    - #### public java.beans.PropertyDescriptor getPropertyDescriptor(java.lang.String name)

    - #### public java.beans.PropertyDescriptor[] getPropertyDescriptors()

    - #### public org.springframework.core.convert.TypeDescriptor getTypeDescriptor(java.beans.PropertyDescriptor pd)