一、 Spring 对象拷贝的具体实现
Spring 对象拷贝,基于反射和内省,将源对象字段值装填到目标对象字段上。主要分以下两步:
- 通过内省,获取源对象和目标对象的属性描述器;
- 通过反射,解析源属性值,赋值到目标属性中;
1 | /** |
二、 BeanUtils.copyProperties实现原理
根据以上分析,整合出 Spring 对象拷贝的实现原理:

通过内省机制,对 Bean 进行拆分,得到每个属性的描述器,缓存在 Map 中,Key为变量名,Value为属性描述器。属性描述器主要包括:属性名称、读取属性值的方法、设置属性值的方法。拷贝过程中,先获取目标属性的写入方法,再获取对应源属性的读取方法,最后通过反射拷贝属性值。
三、JavaBean内省机制
JavaBean 内省,是建立在反射基础上的,通过解析 Bean各个属性的描述器,以便通过属性描述器来操作 Bean 的一种机制。反射是将 Java 类中的各种成分映射成相应的 Java 类,可以获取所有属性以及调用任何方法。与反射不同的是,内省是通过属性描述器来暴露一个 Bean 的属性、方法和时间的,而且只有符合 JavaBean 规则的类的成员才可以调用内生 API 进行操作。

内省在 java.beans.Introspector中的具体实现:
1 | // 获取所有的 public 方法 |
由此可以看出,一个类的方法名称、入参个数、反参类型是JavaBean 内省的主要要素,可以总结为:
- 只能内省一个类暴露的
public非静态方法; - 可以内省标准化的
set方法,如void setAge(Integer age); - 可以内省标准化的
get方法,如ResultType getAge(); - 可以内省设置索引属性的方法,如
setChild(Integer index, Child child); - 可以内省获取索引属性的方法,如
getChild(Integer index); - 可以内省获取基本类型布尔值的且以
is开头的方法,如boolean isMale();
五、总结
Spring 对象拷贝,基于反射和内省机制,通过属性描述器,将源属性值写入目标属性。如今 Spring 架构已被广泛使用,旗下各种好用的工具也是顺手拈来,但无端的滥用也潜藏着一些问题。比如 Spring 对象拷贝,要求操作的对象必须符合 JavaBean 规范,否则将无法拷贝。如拷贝包装类型的布尔值,其读取方法为 Boolean isMale ,不符合 JavaBean 规范,对应的目标属性值一定是 null。































