功能
reflection 包下的类主要负责的功能是 mybatis 反射实例化对象以及赋值,mybatis之所以可以将返回结果封装成pojo实体类,都是通过reflection包下的相关类通过反射去完成这个操作的。reflection 包下有几个核心的类,MetaObject、Reflector、MetaClass、以及ObjectWrapper。
它的这个设计思路是,首先将一个class的所有的字段、方法、构造等信息全部都存在 reflector 中,然后再通过 metaObject 的静态方法构造一个元数据对象,通过 ObjectWrapper 去调用 reflaector 中的getSet方法去赋值以及构造方法初始化对象。
UML
MetaClass、MetaObject 相当于是一个封装类,内部封装了 reflector 等元数据信息
Reflector 中有一些关于一个class的详细描述,有type(Class对象)、getMethdos、setMethods、defaultConstructor、readablePropertyNames(get方法的字段名字)、writablePropertyNames(set方法的字段名字)、setTypes(set方法的入参)、caseInsensitivePropertyMap(getset方法的名字大写)等属性。
DefaultReflectorFactory 是一个构造工厂,顾名思义,是用来构造 Reflector 的,MetaClass 要想获得这个对象,是通过一个静态方法 forClass 来拿的。
MetaObject 内部的一些属性:
originalObject:实际对象
ObjectWrapper:封装了调用set方法往对象设值的封装类
ObjectFactory:反射实例化对象的工厂方法
objectWrapperFactory:生成 ObjectWrapper 的工厂
ReflectorFactory: 获取反射元数据信息的工厂
ObjectWrapper 是具体往对象中设置的封装类,他有三个主要实现类,通过名字也可以看出来各自的作用:
BeanWrapper:实例单一对象的处理类
MapWrapper: 针对Map类型的处理类
CollectionWrapper:针对集合的处理类
代码详解
MetaClass 的获取是通过 forClass 来获取的,在 .XMLMapperBuilder的validateCollection方法中就有一个使用示例,一般用 MetaClass 都是来验证这个类中的某个字段是否存在,比如 validateCollection 验证这个类是否有set方法。
protected void validateCollection(XNode context, Class<?> enclosingType) {
if ("collection".equals(context.getName()) && context.getStringAttribute("resultMap") == null
&& context.getStringAttribute("javaType") == null) {
// 获取 metaClass
MetaClass metaResultType = MetaClass.forClass(enclosingType, configuration.getReflectorFactory());
String property = context.getStringAttribute("property");
// 判断是否有setter方法
if (!metaResultType.hasSetter(property)) {
throw new BuilderException(
"Ambiguous collection type for property '" + property + "'. You must specify 'javaType' or 'resultMap'.");
}
}
}
MetaClass.forClass() 方法中,会去调用构造方法,在构造方法中,会通过ReflectorFactory 的findForClass() 方法去构建一个 reflector 出来,这里如果你没有配置的话默认是 DefaultReflectorFactory类
public static MetaClass forClass(Class<?>