Class BeanInfoGen
java.beans.BeanInfo class for a bean class.
By default the generated BeanInfo fully replicates the information that ordinary
introspection would have produced in the absence of any explicit BeanInfo for the
bean class -- its bean descriptor, property descriptors, event-set descriptors and method
descriptors.
Properties may be excluded from the generated property descriptors in two ways: by name (any
property whose name appears in excludedPropertyNames) and by type (any property whose
type is assignable to one of the Class objects in excludedPropertyTypes).
For an indexed property, exclusion by type considers both the array type and the element
type, independent of which accessor convention defined the property (an array-valued accessor such
as String[] getTags(), a single-index accessor such as String getTags(int),
or both). Whichever of the two types the property descriptor does not directly report is derived
from the other, and the property is excluded if either is assignable to an excluded type. Thus an
indexed property with element type String is excluded whether String.class
or String[].class is given, and identically regardless of how it was declared.
Because the generated getPropertyDescriptors() returns a non-null array, the JavaBeans
Introspector uses it verbatim rather than rediscovering properties reflectively, so
the accessor methods of an excluded property are no longer seen as constituting a JavaBeans
property. The methods themselves remain ordinary public methods and are still reported among the
method descriptors.-
Method Summary
Modifier and TypeMethodDescriptionstatic StringexplicitBeanInfoClassSourceForBeanClass(Class beanClass, Set excludedPropertyNames, Set excludedPropertyTypes) Convenience overload equivalent toexplicitBeanInfoClassSourceForBeanClass(Class, Set, Set, boolean, boolean)withsuppressDescriptorCachingandincludeMLoggingbothfalse.static StringexplicitBeanInfoClassSourceForBeanClass(Class beanClass, Set excludedPropertyNames, Set excludedPropertyTypes, boolean suppressDescriptorCaching, boolean includeMLogging) Generates Java source for an explicitBeanInfoclass describingbeanClass.static void
-
Method Details
-
explicitBeanInfoClassSourceForBeanClass
public static String explicitBeanInfoClassSourceForBeanClass(Class beanClass, Set excludedPropertyNames, Set excludedPropertyTypes) throws IntrospectionException, IOException Convenience overload equivalent toexplicitBeanInfoClassSourceForBeanClass(Class, Set, Set, boolean, boolean)withsuppressDescriptorCachingandincludeMLoggingbothfalse. The generatedBeanInfotherefore caches its descriptors (see the multi-argument overload for the trade-offs that implies) and silently omits any descriptor that proves invalid at runtime.- Throws:
IntrospectionExceptionIOException
-
explicitBeanInfoClassSourceForBeanClass
public static String explicitBeanInfoClassSourceForBeanClass(Class beanClass, Set excludedPropertyNames, Set excludedPropertyTypes, boolean suppressDescriptorCaching, boolean includeMLogging) throws IntrospectionException, IOException Generates Java source for an explicitBeanInfoclass describingbeanClass.Descriptor caching (
suppressDescriptorCaching)When
suppressDescriptorCachingisfalse(the default), the generatedBeanInfocomputes itsBeanDescriptorand its property, event-set, and method descriptor arrays once, into instance fields, and each accessor returns that cached state (handing back a defensiveclone()of the arrays). This matches how the class is actually consumed:Introspectormaintains its own per-class cache ofBeanInfoinstances and reuses a single instance for every introspection of the bean, so regenerating and re-validating every descriptor on each accessor call would be almost pure waste.Caching has a cost, though, and it is not primarily about CPU. The cached descriptor objects are shared across all callers, and
java.beansdescriptors are mutable (setShortDescription,setValue,setBound,setExpert, etc.). Because theIntrospectorcaches theBeanInfoinstance, a single caller that mutates a returned descriptor poisons that shared object for every future caller, process-wide and indefinitely. The defensive arrayclone()protects the membership of each descriptor set (no caller can add or remove descriptors), but it does not protect the mutable state within a descriptor.Set
suppressDescriptorCachingtotrueto have every accessor rebuild its descriptors fresh on each call. This is slower and produces more garbage, but it is the only configuration that gives true per-caller isolation: a mutation by one caller cannot propagate to other callers or persist into the future. (Java's bean APIs offer no read-only descriptor variant, and copy-on-read in the cached case would defeat caching entirely, so this binary flag is the practical seam.) Prefer it for security-sensitive deployments in which untrusted code may receive theBeanInfoand could mutate its descriptors.Resilience logging (
includeMLogging)A generated
BeanInfomay run on a JVM or library version where some method, property, or event that existed when it was generated is no longer present; such descriptors are skipped rather than allowed to abort the wholeBeanInfo. WhenincludeMLoggingistrue, each skip is logged atWARNINGviacom.mchange.v2.log; whenfalse, skips are silent.- Parameters:
suppressDescriptorCaching- iftrue, rebuild descriptors fresh on every accessor call (isolated but slow) instead of caching and sharing them (fast but mutably shared)includeMLogging- iftrue, log aWARNINGwhenever a descriptor is skipped because it is not valid in the runtime environment- Throws:
IntrospectionExceptionIOException
-
main
-