Spring Beans - IoC Container and Dependency Injection providing comprehensive bean management infrastructure and dependency injection capabilities.
—
Powerful property binding system with automatic type conversion, nested property access, and comprehensive editor support for converting between string representations and Java objects. This system forms the foundation for Spring's data binding capabilities in web applications and configuration processing.
Core interface for accessing and modifying properties on target objects with support for nested properties and automatic type conversion.
/**
* Common interface for classes that can access named properties (such as bean properties of an object or fields in an object).
*/
interface PropertyAccessor {
/** Path separator for nested properties. */
String NESTED_PROPERTY_SEPARATOR = ".";
/** Path separator for nested properties. */
char NESTED_PROPERTY_SEPARATOR_CHAR = '.';
/** Marker that indicates the start of a property key for an indexed or mapped property. */
String PROPERTY_KEY_PREFIX = "[";
/** Marker that indicates the start of a property key for an indexed or mapped property. */
char PROPERTY_KEY_PREFIX_CHAR = '[';
/** Marker that indicates the end of a property key for an indexed or mapped property. */
String PROPERTY_KEY_SUFFIX = "]";
/** Marker that indicates the end of a property key for an indexed or mapped property. */
char PROPERTY_KEY_SUFFIX_CHAR = ']';
/**
* Determine whether the specified property is readable.
* @param propertyName the property to check
* @return whether the property is readable
*/
boolean isReadableProperty(String propertyName);
/**
* Determine whether the specified property is writable.
* @param propertyName the property to check
* @return whether the property is writable
*/
boolean isWritableProperty(String propertyName);
/**
* Determine the property type for the specified property.
* @param propertyName the property to check
* @return the type of the property, or null if not determinable
* @throws InvalidPropertyException if there is no such property or if the property isn't readable
*/
Class<?> getPropertyType(String propertyName) throws BeansException;
/**
* Return a type descriptor for the specified property.
* @param propertyName the property to check
* @return the type descriptor for the particular property
* @throws InvalidPropertyException if there is no such property or if the property isn't readable
*/
TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException;
/**
* Get the current value of the specified property.
* @param propertyName the name of the property to get the value of
* @return the value of the property
* @throws InvalidPropertyException if there is no such property or if the property isn't readable
* @throws PropertyAccessException if the property was valid but the accessor method failed
*/
Object getPropertyValue(String propertyName) throws BeansException;
/**
* Set the specified value as current property value.
* @param propertyName the name of the property to set the value of
* @param value the new value
* @throws InvalidPropertyException if there is no such property or if the property isn't writable
* @throws PropertyAccessException if the property was valid but the accessor method failed or a type mismatch occurred
*/
void setPropertyValue(String propertyName, Object value) throws BeansException;
/**
* Set the specified value as current property value.
* @param pv an object containing the new property value
* @throws InvalidPropertyException if there is no such property or if the property isn't writable
* @throws PropertyAccessException if the property was valid but the accessor method failed or a type mismatch occurred
*/
void setPropertyValue(PropertyValue pv) throws BeansException;
/**
* Perform a batch update from a Map.
* @param map Map containing properties to set, as name-value pairs
* @throws InvalidPropertyException if there is no such property or if the property isn't writable
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions occurred for specific properties during the batch update
*/
void setPropertyValues(Map<?, ?> map) throws BeansException;
/**
* The preferred way to perform a batch update.
* @param pvs PropertyValues to set on the target object
* @throws InvalidPropertyException if there is no such property or if the property isn't writable
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions occurred for specific properties during the batch update
*/
void setPropertyValues(PropertyValues pvs) throws BeansException;
/**
* Perform a batch update with more control over behavior.
* @param pvs PropertyValues to set on the target object
* @param ignoreUnknown should we ignore unknown properties (not found in the bean)
* @throws InvalidPropertyException if there is no such property or if the property isn't writable
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions occurred for specific properties during the batch update
*/
void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown) throws BeansException;
/**
* Perform a batch update with full control over behavior.
* @param pvs PropertyValues to set on the target object
* @param ignoreUnknown should we ignore unknown properties (not found in the bean)
* @param ignoreInvalid should we ignore invalid properties (found but not accessible)
* @throws InvalidPropertyException if there is no such property or if the property isn't writable
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions occurred for specific properties during the batch update
*/
void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException;
}Central interface for accessing and manipulating the properties of a bean instance, combining property access with comprehensive type conversion.
/**
* The central interface of Spring's low-level JavaBeans infrastructure.
*/
interface BeanWrapper extends ConfigurablePropertyAccessor {
/**
* Change the wrapped object. Implementations are required to allow the type of the wrapped object to change.
* @param object the new wrapped object
*/
void setWrappedInstance(Object object);
/**
* Return the bean instance wrapped by this object.
* @return the bean instance, or null if none set
*/
Object getWrappedInstance();
/**
* Return the type of the wrapped bean instance.
* @return the type of the wrapped bean instance, or null if no wrapped object has been set
*/
Class<?> getWrappedClass();
/**
* Obtain the PropertyDescriptors for the wrapped object (as determined by standard JavaBeans introspection).
* @return the PropertyDescriptors for the wrapped object
*/
PropertyDescriptor[] getPropertyDescriptors();
/**
* Obtain the property descriptor for a specific property of the wrapped object.
* @param propertyName the property to obtain the descriptor for
* @return the property descriptor for the specified property
* @throws InvalidPropertyException if there is no such property
*/
PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;
}Default implementation of the BeanWrapper interface that provides comprehensive property access and type conversion capabilities.
/**
* Default BeanWrapper implementation that should be sufficient for all typical use cases.
*/
class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements BeanWrapper {
/**
* Create a new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards.
*/
public BeanWrapperImpl();
/**
* Create a new BeanWrapperImpl for the given object.
* @param object the object wrapped by this BeanWrapper
*/
public BeanWrapperImpl(Object object);
/**
* Create a new BeanWrapperImpl, wrapping a new instance of the specified class.
* @param clazz class to instantiate and wrap
*/
public BeanWrapperImpl(Class<?> clazz);
/**
* Create a new BeanWrapperImpl for the given object, registering a nested path that the object is in.
* @param object the object wrapped by this BeanWrapper
* @param nestedPath the nested path of the object
* @param rootObject the root object at the top of the path
*/
public BeanWrapperImpl(Object object, String nestedPath, Object rootObject);
/**
* Set a bean instance to hold, without any unwrapping of Optional.
* @param object the actual target object
*/
public void setBeanInstance(Object object);
/**
* Convert the given value for the specified property to the latter's type.
* @param value the value to convert (may be null)
* @param propertyName the target property
* @return the converted value
* @throws TypeMismatchException if type conversion failed
*/
public Object convertForProperty(Object value, String propertyName) throws TypeMismatchException;
}Container for PropertyValue objects, typically representing one update for a JavaBean.
/**
* Holder containing one or more PropertyValue objects, typically comprising one update for a specific target bean.
*/
interface PropertyValues {
/**
* Return an array of the PropertyValue objects held in this object.
* @return an array of the PropertyValue objects held in this object (never null)
*/
PropertyValue[] getPropertyValues();
/**
* Return the property value with the given name, if any.
* @param propertyName the name to search for
* @return the property value, or null if none
*/
PropertyValue getPropertyValue(String propertyName);
/**
* Return the changes since the previous PropertyValues.
* @param old the old property values
* @return the updated or new properties
*/
PropertyValues changesSince(PropertyValues old);
/**
* Is there a property value (or other processing entry) for this property?
* @param propertyName the name of the property we're interested in
* @return whether there is a property value for this property
*/
boolean contains(String propertyName);
/**
* Does this holder not contain any PropertyValue objects at all?
* @return whether this holder does not contain any PropertyValue objects
*/
boolean isEmpty();
/**
* Return the number of PropertyValue objects held in this object.
* @return the number of PropertyValue objects held in this object
*/
int size();
}
/**
* The default implementation of the PropertyValues interface.
*/
class MutablePropertyValues implements PropertyValues {
/**
* Creates a new empty MutablePropertyValues object.
*/
public MutablePropertyValues();
/**
* Deep copy constructor.
* @param original the PropertyValues to copy
*/
public MutablePropertyValues(PropertyValues original);
/**
* Construct a new MutablePropertyValues object from a Map.
* @param original a Map with property values keyed by property name Strings
*/
public MutablePropertyValues(Map<?, ?> original);
/**
* Construct a new MutablePropertyValues object using the given List of PropertyValue objects as-is.
* @param propertyValueList a List of PropertyValue objects
*/
public MutablePropertyValues(List<PropertyValue> propertyValueList);
/**
* Return the underlying List of PropertyValue objects in its raw form.
* @return the underlying List of PropertyValue objects
*/
public List<PropertyValue> getPropertyValueList();
/**
* Add all property values from the given PropertyValues object.
* @param other the PropertyValues object to add property values from
* @return this in order to allow for adding multiple property values in a chain
*/
public MutablePropertyValues addPropertyValues(PropertyValues other);
/**
* Add all property values from the given Map.
* @param other a Map with property values keyed by property name Strings
* @return this in order to allow for adding multiple property values in a chain
*/
public MutablePropertyValues addPropertyValues(Map<?, ?> other);
/**
* Add a PropertyValue object, replacing any existing one for the corresponding property or getting merged with it (if applicable).
* @param pv the PropertyValue object to add
* @return this in order to allow for adding multiple property values in a chain
*/
public MutablePropertyValues addPropertyValue(PropertyValue pv);
/**
* Add a PropertyValue object, replacing any existing one for the corresponding property.
* @param propertyName name of the property
* @param propertyValue value of the property
* @return this in order to allow for adding multiple property values in a chain
*/
public MutablePropertyValues addPropertyValue(String propertyName, Object propertyValue);
/**
* Add a PropertyValue object, replacing any existing one for the corresponding property.
* @param propertyName name of the property
* @param propertyValue value of the property
* @return this in order to allow for adding multiple property values in a chain
*/
public MutablePropertyValues add(String propertyName, Object propertyValue);
/**
* Remove the given PropertyValue, if contained.
* @param pv the PropertyValue to remove
*/
public void removePropertyValue(PropertyValue pv);
/**
* Overloaded version of removePropertyValue that takes a property name.
* @param propertyName name of the property to remove
*/
public void removePropertyValue(String propertyName);
}
/**
* Object to hold information and value for an individual bean property.
*/
class PropertyValue extends BeanMetadataAttributeAccessor {
/**
* Create a new PropertyValue instance.
* @param name the name of the property (never null)
* @param value the value of the property (possibly before type conversion)
*/
public PropertyValue(String name, Object value);
/**
* Copy constructor.
* @param original the PropertyValue to copy (never null)
*/
public PropertyValue(PropertyValue original);
/**
* Constructor that exposes a new value for an original value holder.
* @param original the PropertyValue to link to (never null)
* @param newValue the new value to apply
*/
public PropertyValue(PropertyValue original, Object newValue);
/**
* Return the name of the property.
* @return the name of the property (never null)
*/
public String getName();
/**
* Return the value of the property.
* @return the value of the property (possibly before type conversion)
*/
public Object getValue();
/**
* Return the original PropertyValue instance for this value holder.
* @return the original PropertyValue (either a source of this value holder or this value holder itself)
*/
public PropertyValue getOriginalPropertyValue();
/**
* Set whether this is an optional value, that is, to be ignored when no corresponding property exists on the target class.
* @param optional whether this is an optional value
*/
public void setOptional(boolean optional);
/**
* Return whether this is an optional value, that is, to be ignored when no corresponding property exists on the target class.
* @return whether this is an optional value
*/
public boolean isOptional();
/**
* Return whether this holder contains a converted value already (true), or whether the value still needs to be converted (false).
* @return whether this holder contains a converted value already
*/
public synchronized boolean isConverted();
/**
* Set the converted value of the constructor argument, after processed type conversion.
* @param value the converted value
*/
public synchronized void setConvertedValue(Object value);
/**
* Return the converted value of the constructor argument, after processed type conversion.
* @return the converted value
*/
public synchronized Object getConvertedValue();
}Core interfaces and classes for type conversion between different object types.
/**
* Interface that defines type conversion methods.
*/
interface TypeConverter {
/**
* Convert the value to the required type (if necessary from a String).
* @param value the value to convert
* @param requiredType the type we must convert to (or null if not known)
* @return the new value, possibly the result of type conversion
* @throws TypeMismatchException if type conversion failed
*/
<T> T convertIfNecessary(Object value, Class<T> requiredType) throws TypeMismatchException;
/**
* Convert the value to the required type (if necessary from a String).
* @param value the value to convert
* @param requiredType the type we must convert to (or null if not known)
* @param methodParam the method parameter that is the target of the conversion
* @return the new value, possibly the result of type conversion
* @throws TypeMismatchException if type conversion failed
*/
<T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam) throws TypeMismatchException;
/**
* Convert the value to the required type (if necessary from a String).
* @param value the value to convert
* @param requiredType the type we must convert to (or null if not known)
* @param field the reflective field that is the target of the conversion
* @return the new value, possibly the result of type conversion
* @throws TypeMismatchException if type conversion failed
*/
<T> T convertIfNecessary(Object value, Class<T> requiredType, Field field) throws TypeMismatchException;
/**
* Convert the value to the required type (if necessary from a String).
* @param value the value to convert
* @param requiredType the type we must convert to (or null if not known)
* @param typeDescriptor the type descriptor to use (may be null)
* @return the new value, possibly the result of type conversion
* @throws TypeMismatchException if type conversion failed
*/
<T> T convertIfNecessary(Object value, Class<T> requiredType, TypeDescriptor typeDescriptor) throws TypeMismatchException;
}
/**
* Simple implementation of the TypeConverter interface that does not operate on a specific target object.
*/
class SimpleTypeConverter extends TypeConverterSupport {
/**
* Create a new SimpleTypeConverter.
*/
public SimpleTypeConverter();
}Usage Examples:
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
// Basic property access
Person person = new Person();
BeanWrapper wrapper = new BeanWrapperImpl(person);
// Set simple properties
wrapper.setPropertyValue("name", "John Doe");
wrapper.setPropertyValue("age", 30);
wrapper.setPropertyValue("active", true);
// Get property values
String name = (String) wrapper.getPropertyValue("name");
Integer age = (Integer) wrapper.getPropertyValue("age");
// Nested property access
wrapper.setPropertyValue("address.street", "123 Main St");
wrapper.setPropertyValue("address.city", "New York");
// Batch property updates
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.addPropertyValue("name", "Jane Smith");
pvs.addPropertyValue("email", "jane@example.com");
pvs.addPropertyValue("birthDate", "1990-01-15");
wrapper.setPropertyValues(pvs);
// Array and collection property access
wrapper.setPropertyValue("hobbies[0]", "Reading");
wrapper.setPropertyValue("hobbies[1]", "Swimming");
// Map property access
wrapper.setPropertyValue("attributes[title]", "Manager");
wrapper.setPropertyValue("attributes[department]", "Engineering");
// Type conversion example
SimpleTypeConverter converter = new SimpleTypeConverter();
Date date = converter.convertIfNecessary("2023-01-15", Date.class);
List<String> list = converter.convertIfNecessary("a,b,c", List.class);Registry and support for PropertyEditor instances used in type conversion.
/**
* Interface for strategies that register custom property editors with a property editor registry.
*/
interface PropertyEditorRegistrar {
/**
* Register custom PropertyEditors with the given PropertyEditorRegistry.
* @param registry the PropertyEditorRegistry to register the custom PropertyEditors with
*/
void registerCustomEditors(PropertyEditorRegistry registry);
}
/**
* Encapsulates methods for registering JavaBeans PropertyEditors.
*/
interface PropertyEditorRegistry {
/**
* Register the given custom property editor for all properties of the given type.
* @param requiredType the type of the property
* @param propertyEditor the editor to register
*/
void registerCustomEditor(Class<?> requiredType, PropertyEditor propertyEditor);
/**
* Register the given custom property editor for the given type and property, or for all properties of the given type.
* @param requiredType the type of the property (can be null if a property is given but should be specified in any case for consistency checking)
* @param propertyPath the path of the property (name or nested path), or null if registering an editor for all properties of the given type
* @param propertyEditor the editor to register
*/
void registerCustomEditor(Class<?> requiredType, String propertyPath, PropertyEditor propertyEditor);
/**
* Find a custom property editor for the given type and property.
* @param requiredType the type of the property (can be null if a property is given but should be specified in any case for consistency checking)
* @param propertyPath the path of the property (name or nested path), or null if looking for an editor for all properties of the given type
* @return the registered editor, or null if none
*/
PropertyEditor findCustomEditor(Class<?> requiredType, String propertyPath);
}Comprehensive collection of built-in PropertyEditor implementations for converting between string representations and Java objects.
/**
* Property editor for Boolean/boolean properties.
*/
class CustomBooleanEditor extends PropertyEditorSupport {
public CustomBooleanEditor(boolean allowEmpty);
public CustomBooleanEditor(String trueString, String falseString, boolean allowEmpty);
}
/**
* Property editor for any Number subclass such as Short, Integer, Long, BigInteger, Float, Double, BigDecimal.
*/
class CustomNumberEditor extends PropertyEditorSupport {
public CustomNumberEditor(Class<? extends Number> numberClass, boolean allowEmpty) throws IllegalArgumentException;
public CustomNumberEditor(Class<? extends Number> numberClass, NumberFormat numberFormat, boolean allowEmpty) throws IllegalArgumentException;
}
/**
* Property editor for Date properties.
*/
class CustomDateEditor extends PropertyEditorSupport {
public CustomDateEditor(DateFormat dateFormat, boolean allowEmpty);
public CustomDateEditor(DateFormat dateFormat, boolean allowEmpty, int exactDateLength);
}
/**
* Property editor for Character properties.
*/
class CharacterEditor extends PropertyEditorSupport {
public CharacterEditor(boolean allowEmpty);
}
/**
* Property editor for Collections, converting any source Collection to a given target Collection type.
*/
class CustomCollectionEditor extends PropertyEditorSupport {
public CustomCollectionEditor(Class<? extends Collection> collectionType);
public CustomCollectionEditor(Class<? extends Collection> collectionType, boolean nullAsEmptyCollection);
}
/**
* Property editor for Maps, converting any source Map to a given target Map type.
*/
class CustomMapEditor extends PropertyEditorSupport {
public CustomMapEditor(Class<? extends Map> mapType);
public CustomMapEditor(Class<? extends Map> mapType, boolean nullAsEmptyMap);
}
/**
* Editor for String arrays.
*/
class StringArrayPropertyEditor extends PropertyEditorSupport {
public static final String DEFAULT_SEPARATOR = ",";
public StringArrayPropertyEditor();
public StringArrayPropertyEditor(String separator);
public StringArrayPropertyEditor(String separator, String charsToDelete);
public StringArrayPropertyEditor(String separator, String charsToDelete, boolean emptyArrayAsNull);
public StringArrayPropertyEditor(String separator, String charsToDelete, boolean emptyArrayAsNull, boolean trimValues);
}
/**
* Property editor for java.io.File descriptors.
*/
class FileEditor extends PropertyEditorSupport {
public FileEditor();
public FileEditor(ResourceEditor resourceEditor);
}
/**
* Editor for java.io.InputStream, converting from a Spring resource location String.
*/
class InputStreamEditor extends PropertyEditorSupport {
public InputStreamEditor();
public InputStreamEditor(ResourceEditor resourceEditor);
}
/**
* Editor for java.io.Reader, converting from a Spring resource location String.
*/
class ReaderEditor extends PropertyEditorSupport {
public ReaderEditor();
public ReaderEditor(ResourceEditor resourceEditor);
}
/**
* Editor for java.net.URL, converting from a Spring resource location String.
*/
class URLEditor extends PropertyEditorSupport {
public URLEditor();
public URLEditor(ResourceEditor resourceEditor);
}
/**
* Editor for java.net.URI, converting from a Spring resource location String.
*/
class URIEditor extends PropertyEditorSupport {
public URIEditor();
public URIEditor(ClassLoader classLoader);
public URIEditor(ClassLoader classLoader, boolean encode);
}
/**
* Editor for java.nio.file.Path, converting from a Spring resource location String.
*/
class PathEditor extends PropertyEditorSupport {
public PathEditor();
public PathEditor(ResourceEditor resourceEditor);
}
/**
* Editor for java.util.Locale, converting from a String representation to a Locale object.
*/
class LocaleEditor extends PropertyEditorSupport {
public LocaleEditor();
}
/**
* Editor for java.util.TimeZone, converting from a String representation to a TimeZone object.
*/
class TimeZoneEditor extends PropertyEditorSupport {
public TimeZoneEditor();
}
/**
* Editor for java.time.ZoneId, converting from a String representation to a ZoneId object.
*/
class ZoneIdEditor extends PropertyEditorSupport {
public ZoneIdEditor();
}
/**
* Editor for java.util.regex.Pattern, converting from a String representation to a Pattern object.
*/
class PatternEditor extends PropertyEditorSupport {
public PatternEditor();
public PatternEditor(int flags);
}
/**
* Editor for java.nio.charset.Charset, converting from a String representation to a Charset object.
*/
class CharsetEditor extends PropertyEditorSupport {
public CharsetEditor();
}
/**
* Editor for java.lang.Class, converting from a String representation to a Class object.
*/
class ClassEditor extends PropertyEditorSupport {
public ClassEditor();
public ClassEditor(ClassLoader classLoader);
}
/**
* Property editor for an array of Classes, converting from a comma-delimited String to a Class array.
*/
class ClassArrayEditor extends PropertyEditorSupport {
public ClassArrayEditor();
public ClassArrayEditor(ClassLoader classLoader);
}
/**
* Editor for java.util.UUID, converting from a String representation to a UUID object.
*/
class UUIDEditor extends PropertyEditorSupport {
public UUIDEditor();
}
/**
* Editor for java.util.Currency, converting from a String representation to a Currency object.
*/
class CurrencyEditor extends PropertyEditorSupport {
public CurrencyEditor();
}Utility classes that provide helper methods for property access operations.
/**
* Static convenience methods for JavaBeans.
*/
class BeanUtils {
/**
* Instantiate a class using its 'no-arg' constructor.
* @param clazz the class to instantiate
* @return the new instance
* @throws BeanInstantiationException if the bean cannot be instantiated
*/
public static <T> T instantiateClass(Class<T> clazz) throws BeanInstantiationException;
/**
* Instantiate a class using the given constructor.
* @param ctor the constructor to use
* @param args the constructor arguments to apply
* @return the new instance
* @throws BeanInstantiationException if the bean cannot be instantiated
*/
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException;
/**
* Find a method with the given method name and parameter types.
* @param clazz the class to introspect
* @param methodName the name of the method
* @param paramTypes the parameter types of the method
* @return the Method object, or null if none found
*/
public static Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes);
/**
* Find a method with the given method name and minimal parameters.
* @param clazz the class to introspect
* @param methodName the name of the method
* @return the Method object, or null if none found
*/
public static Method findMethodWithMinimalParameters(Class<?> clazz, String methodName) throws IllegalArgumentException;
/**
* Find a method with the given method name and minimal parameters.
* @param methods the candidate methods
* @param methodName the name of the method
* @return the Method object, or null if none found
*/
public static Method findMethodWithMinimalParameters(Method[] methods, String methodName) throws IllegalArgumentException;
/**
* Find a method with the given method name and the given parameter types.
* @param clazz the class to introspect
* @param methodName the name of the method
* @param paramTypes the parameter types of the method
* @return the Method object, or null if none found
*/
public static Method resolveSignature(String signature, Class<?> clazz);
/**
* Retrieve the JavaBeans PropertyDescriptors of a given class.
* @param clazz the Class to retrieve the PropertyDescriptors for
* @return an array of PropertyDescriptors for the given class
* @throws BeansException if an error occurs
*/
public static PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) throws BeansException;
/**
* Retrieve the JavaBeans PropertyDescriptor for the given property.
* @param clazz the Class to retrieve the PropertyDescriptor for
* @param propertyName the name of the property
* @return the PropertyDescriptor for the given property
* @throws BeansException if an error occurs
*/
public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String propertyName) throws BeansException;
/**
* Find a JavaBeans PropertyDescriptor for the given method.
* @param method the method to find a corresponding PropertyDescriptor for
* @return the corresponding PropertyDescriptor, or null if none
* @throws BeansException if an error occurs
*/
public static PropertyDescriptor findPropertyForMethod(Method method) throws BeansException;
/**
* Find a JavaBeans PropertyDescriptor for the given method.
* @param method the method to find a corresponding PropertyDescriptor for
* @param clazz the (most specific) class to introspect for descriptors
* @return the corresponding PropertyDescriptor, or null if none
* @throws BeansException if an error occurs
*/
public static PropertyDescriptor findPropertyForMethod(Method method, Class<?> clazz) throws BeansException;
/**
* Find a JavaBeans setter method for the given property.
* @param clazz the Class to find the method on
* @param propertyName the property name
* @return the setter method, or null if none
*/
public static Method findPropertyType(String propertyName, Class<?>... beanClasses);
/**
* Obtain a new MethodParameter object for the write method of the specified property.
* @param pd the PropertyDescriptor for the property
* @return a corresponding MethodParameter object
*/
public static MethodParameter getWriteMethodParameter(PropertyDescriptor pd);
/**
* Check if the given type represents a "simple" property.
* @param type the type to check
* @return whether the given type represents a "simple" property
*/
public static boolean isSimpleProperty(Class<?> type);
/**
* Check if the given type represents a "simple" value type.
* @param type the type to check
* @return whether the given type represents a "simple" value type
*/
public static boolean isSimpleValueType(Class<?> type);
/**
* Copy the property values of the given source bean into the target bean.
* @param source the source bean
* @param target the target bean
* @throws BeansException if the copying failed
*/
public static void copyProperties(Object source, Object target) throws BeansException;
/**
* Copy the property values of the given source bean into the given target bean.
* @param source the source bean
* @param target the target bean
* @param editable the class (or interface) to restrict property setting to
* @throws BeansException if the copying failed
*/
public static void copyProperties(Object source, Object target, Class<?> editable) throws BeansException;
/**
* Copy the property values of the given source bean into the given target bean.
* @param source the source bean
* @param target the target bean
* @param ignoreProperties array of property names to ignore
* @throws BeansException if the copying failed
*/
public static void copyProperties(Object source, Object target, String... ignoreProperties) throws BeansException;
}
/**
* Utility methods for property access, particularly for bean property paths.
*/
class PropertyAccessorUtils {
/**
* Determine whether the given registered path matches the given property path.
* @param registeredPath the registered path
* @param propertyPath the property path to check
* @return whether the paths match
*/
public static boolean matchesProperty(String registeredPath, String propertyPath);
/**
* Determine the canonical name for the given property path.
* @param propertyPath the original property path
* @return the canonical property path
*/
public static String canonicalPropertyName(String propertyPath);
/**
* Determine all canonical names for the given property paths.
* @param propertyNames the original property names
* @return the canonical property names array
*/
public static String[] canonicalPropertyNames(String[] propertyNames);
/**
* Return the actual property name for the given property path.
* @param propertyPath the property path to check
* @return the actual property name, or null if none
*/
public static String getPropertyName(String propertyPath);
/**
* Check whether the given property path indicates an indexed or nested property.
* @param propertyPath property path to check
* @return whether the path indicates an indexed or nested property
*/
public static boolean isNestedOrIndexedProperty(String propertyPath);
/**
* Determine the first nested property separator in the given property path.
* @param propertyPath the property path to check
* @return the index of the nested property separator, or -1 if none
*/
public static int getFirstNestedPropertySeparatorIndex(String propertyPath);
/**
* Determine the first nested property separator in the given property path.
* @param propertyPath the property path to check
* @return the index of the nested property separator, or -1 if none
*/
public static int getLastNestedPropertySeparatorIndex(String propertyPath);
}
/**
* Utility class for working with property descriptors.
*/
class PropertyDescriptorUtils {
/**
* See PropertyDescriptor.hashCode().
* @param pd the PropertyDescriptor
* @return the hash code
*/
public static int hashCode(PropertyDescriptor pd);
/**
* See PropertyDescriptor.equals(Object).
* @param pd the PropertyDescriptor
* @param otherPd the other PropertyDescriptor
* @return whether they are equal
*/
public static boolean equals(PropertyDescriptor pd, PropertyDescriptor otherPd);
}Additional classes and interfaces for advanced type conversion.
/**
* Interface for type conversion between Object instances.
*/
interface TypeConverter {
/**
* Convert the value to the required type (may be an array or collection).
* @param value the value to convert (may be null)
* @param requiredType the type we must convert to (must not be null)
* @return the new value, possibly the result of type conversion
* @throws TypeMismatchException if type conversion failed
*/
<T> T convertIfNecessary(Object value, Class<T> requiredType) throws TypeMismatchException;
/**
* Convert the value to the required type.
* @param value the value to convert (may be null)
* @param requiredType the type we must convert to (must not be null)
* @param methodParam the method parameter that is the target of the conversion
* @return the new value, possibly the result of type conversion
* @throws TypeMismatchException if type conversion failed
*/
<T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam) throws TypeMismatchException;
/**
* Convert the value to the required type.
* @param value the value to convert (may be null)
* @param requiredType the type we must convert to (must not be null)
* @param field the reflective field that is the target of the conversion
* @return the new value, possibly the result of type conversion
* @throws TypeMismatchException if type conversion failed
*/
<T> T convertIfNecessary(Object value, Class<T> requiredType, Field field) throws TypeMismatchException;
/**
* Convert the value to the required type.
* @param value the value to convert (may be null)
* @param requiredType the type we must convert to (must not be null)
* @param typeDescriptor the type descriptor to use (may be null)
* @return the new value, possibly the result of type conversion
* @throws TypeMismatchException if type conversion failed
*/
default <T> T convertIfNecessary(Object value, Class<T> requiredType, TypeDescriptor typeDescriptor) throws TypeMismatchException {
throw new UnsupportedOperationException("TypeDescriptor resolution not supported");
}
}
/**
* Simple implementation of the TypeConverter interface that does not operate on a specific target object.
*/
class SimpleTypeConverter extends PropertyEditorRegistrySupport implements TypeConverter {
/**
* Create a new SimpleTypeConverter.
*/
public SimpleTypeConverter();
/**
* Set a ConversionService to use as fallback.
* @param conversionService the ConversionService to use as fallback
*/
public void setConversionService(ConversionService conversionService);
/**
* Return the ConversionService used as fallback.
* @return the ConversionService used as fallback, or null if none
*/
public ConversionService getConversionService();
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework--spring-beans