BeanUtils源码解读

基于 Spring Framework 源码

BeanUtils

JavaBeans的静态便捷方法:用于实例化bean,检查bean属性类型,复制bean属性等。

主要用于框架内,但在某种程度上也适用于应用程序类。

方法摘要

修饰符和类型 方法和描述
static void
copyProperties (java.lang.Object source, java.lang.Object target)

将给定源bean的属性值复制到目标bean中。
static void
copyProperties (java.lang.Object source, java.lang.Object target, java.lang.Class<?> editable)

将给定源bean的属性值复制到给定目标bean中,仅设置在给定“可编辑”类(或接口)中定义的属性。
static void
copyProperties (java.lang.Object source, java.lang.Object target, java.lang.String… ignoreProperties)

将给定源bean的属性值复制到给定的目标bean中,忽略给定的“ignoreProperties”。
static java.lang.reflect.Method
findDeclaredMethod (java.lang.Class<?> clazz, java.lang.String methodName, java.lang.Class<?>… paramTypes)

查找具有给定方法名称和给定参数类型的方法,在给定类或其中一个超类上声明。
static java.lang.reflect.Method
findDeclaredMethodWithMinimalParameters (java.lang.Class<?> clazz, java.lang.String methodName)

查找具有给定方法名称和最小参数(最佳情况:无)的方法,在给定类或其中一个超类上声明。
static java.beans.PropertyEditor
findEditorByConvention (java.lang.Class<?> targetType)

按照’Editor’后缀约定查找JavaBeans PropertyEditor(例如
static java.lang.reflect.Method
findMethod (java.lang.Class<?> clazz, java.lang.String methodName, java.lang.Class<?>… paramTypes)

查找具有给定方法名称和给定参数类型的方法,在给定类或其中一个超类上声明。
static java.lang.reflect.Method
findMethodWithMinimalParameters (java.lang.Class<?> clazz, java.lang.String methodName)

查找具有给定方法名称和最小参数(最佳情况:无)的方法,在给定类或其中一个超类上声明。
static java.lang.reflect.Method
findMethodWithMinimalParameters (java.lang.reflect.Method[] methods, java.lang.String methodName)

在给定的方法列表中查找具有给定方法名称和最小参数(最佳情况:无)的方法。
static <T> java.lang.reflect.Constructor<T>
findPrimaryConstructor (java.lang.Class<T> clazz)

返回提供的类的主要构造函数。
static java.beans.PropertyDescriptor
findPropertyForMethod (java.lang.reflect.Method method)

查找给定方法的JavaBeans PropertyDescriptor ,该方法可以是该bean属性的read方法或write方法。
static java.beans.PropertyDescriptor
findPropertyForMethod (java.lang.reflect.Method method, java.lang.Class<?> clazz)

查找给定方法的JavaBeans PropertyDescriptor ,该方法可以是该bean属性的read方法或write方法。
static java.lang.Class<?>
findPropertyType (java.lang.String propertyName, java.lang.Class<?>… beanClasses)

如果可能,从给定的类/接口确定给定属性的bean属性类型。
static java.beans.PropertyDescriptor
getPropertyDescriptor (java.lang.Class<?> clazz, java.lang.String propertyName)

检索给定属性的JavaBeans PropertyDescriptors 。
static java.beans.PropertyDescriptor[]
getPropertyDescriptors (java.lang.Class<?> clazz)

检索给定类的JavaBeans PropertyDescriptor 。
static MethodParameter
getWriteMethodParameter (java.beans.PropertyDescriptor pd)

获取指定属性的write方法的新MethodParameter对象。
static <T> T
instantiate (java.lang.Class<T> clazz)

已过时。

自JDK 9中的Class.newInstance()弃用之后的Spring 5.0
static <T> T
instantiateClass (java.lang.Class<?> clazz, java.lang.Class<T> assignableTo)

使用其no-arg构造函数实例化一个类,并将新实例作为指定的可赋值类型返回。
static <T> T
instantiateClass (java.lang.Class<T> clazz)

使用其“主要”构造函数(对于Kotlin类,可能具有声明的默认参数)或其默认构造函数(对于常规Java类,期望标准的无参数设置)来实例化类。
static <T> T
instantiateClass (java.lang.reflect.Constructor<T> ctor, java.lang.Object… args)

使用给定构造函数实例化类的便捷方法。
static boolean
isSimpleProperty (java.lang.Class<?> clazz)

检查给定类型是否表示“简单”属性:基元,字符串或其他CharSequence,数字,日期,URI,URL,区域设置,类或相应的数组。
static boolean
isSimpleValueType (java.lang.Class<?> clazz)

检查给定类型是否表示“简单”值类型:基元,枚举,字符串或其他CharSequence,数字,日期,URI,URL,区域设置或类。
static java.lang.reflect.Method
resolveSignature (java.lang.String signature, java.lang.Class<?> clazz)

以methodName[([arg_list])]的形式解析方法签名,其中arg_list是可选的,以逗号分隔的完全限定类型名称列表,并尝试针对提供的Class解析该签名。

1. instantiate 使用 Class方法的构造器来创建对象

3884fdb4dd7dc81ae2e04ba3eb07f690.png

clazz.newInstance();   【JDK 1.6】

只能够调用无参的构造函数,即默认的构造函数。

抛出所有由被调用构造函数抛出的异常。

要求被调用的构造函数是可见的,也即必须是public类型的。

classnewInstance.png

clazz.isInterface(); 【JDK 1.6】

判定指定的 Class 对象是否表示一个接口类型。

如果此对象表示一个接口,则返回 true;否则返回 false。

2. instantiateClass 使用 Class方法的构造器来创建对象

e4ad520bf4fb5084b6ca54beda278be6.png

clazz.getDeclaredConstructor();【JDK 1.6】

classgetDeclaredConstructor.png

Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。

Constructor 允许在将实参与带有底层构造方法的形参的 newInstance() 匹配时进行扩展转换

 

ReflectionUtils.makeAccessible(ctor);   

Accessible 并不是标识方法能否访问的, public的方法Accessible仍为false 使用了method.setAccessible(true)后 性能有了20倍的提升Accessable属性是继承自AccessibleObject 类. 功能是启用或禁用安全检查

3. 类对象方法名称methodName查找findMethod

db1537c6be88bd2f89e247a5ac892ac9.png

class.getMethod;【JDK 1.6】

classgetMethod.png

class.getDeclaredMethod;【JDK 1.6】

classgetDeclaredMethod.png

4. 查找具有最小参数的方法

62ca361357a10410665d8792a050fc4b.png

findMethodWithMinimalParameters

查找具有给定方法名称和最小参数(最佳情况:无)的方法,在给定类或其中一个超类上声明。

findDeclaredMethodWithMinimalParameters

查找具有给定方法名称和最小参数(最佳情况:无)的方法,在给定类或其中一个超类上声明。 将返回公共,受保护,包访问或私有方法。

 

Method.isBridge() ;【JDK 1.6】 

方法来判断一个方法是否是 桥接方法

methodisBridge.png

class.getSuperclass();【JDK 1.6】 

classgetSuperclass.png

5. resolveSignature 针对提供的Class解析该签名

bcdff1a735c53f693d101325e64f6dee.png

StringUtils.commaDelimitedListToStringArray();【Spring StringUtils】

String str = “a,b,c”; 转为 array

springCommaDelimitedListToStringArray.png

clazz.getClassLoader();【JDK 1.6】 

classgetClassLoader.png

6. PropertyDescriptor   利用反射机制获取类中的属性

bd4915e2cef9e14cd519660b09129a00.png

 CachedIntrospectionResults 

对于在应用程序中自己缓存描述符是必需的  class loader,而不是依赖于JDK的全系统BeanInfo缓存

(为了避免class loader关闭时的泄漏)。

PropertyDescriptor 详解

7.   findPropertyType() 获取属性类型

166b6243c1ce8bb90841aecdd80ea1be.png

PropertyDescriptor
属性描述符描述了Java Bean的一个属性 通过一对访问器方法导出。
getPropertyType
返回属性的Java类型信息。

8.  copyProperties()   将给定源bean的属性值复制到目标bean中

BeanUtilscopyProperties.png