MyBatis作为一款ORM框架,主要通过XML定义Object,这就难免用到反射,虽然JDK自带的反射已经方便使用,但是MyBatis依然结合业务功能,将反射功能封装成一个更加易用的包,这个包就在reflection中。
在解析MyBatis的反色包之前,我们需要先通过需要看看MyBatis需要通过反射实现哪些功能。
在MyBatis中,可以方便的获取数组属性和对象属性。比如:student.names[0].firstName
因此,MyBatis将反射获取值分为了两类:
容器类
POJO类
容器类(Collection)通过下标进行取值,而POJO则是通过getter()/setter()进行取值
一个POJO对象拥有两类属性,对象属性以及类信息,在MyBatis中分别通过通过MetaObject和MetaClass对应上述信息。
明白了上述信息,就能理解下面MyBatis反射包中几个关键类的作用:
MetaClass : 保存了POJO的类相关信息,比如拥有的方法hasGetter()/hasSetter()
MetaObject : 保存了POJO对象的相关的信息,比如通过getter()获取值,通过setter()设置值
ObjectWrapper : 用来区别不同的POJO获取属性的不同的方式,比如数组通过索引获取:nums[index],Map通过key获取,POJO通过getter()获取
Relector: 这个类便是MyBatis的反射底层类,它简单的封装了JDK底层的反射,其他类都是调用此类进行反射操作。
接下来开始分析MyBatis的源码。
在relection包中,包含有factory,invoker,property,wrapper 4个包,
factory : 工厂类,主要用来通过反射创建类
invoker: 对POJO的各种类的封装以及缓存,方便直接调用
property : 设置/获取POJO属性的帮助类
wrapper : POJO的包装类,只要需要操作POJO的属性,即可通过此类包装后调用
在MyBatis中,主要通过reflection.SystemMetaObject作为简单工厂使用:
public final class SystemMetaObject {
// 默认创建POJO的工厂类
public static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
// 创建BeanWrapper的工厂类
public static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
// null 对应的Object包装类
public static final MetaObject NULL_META_OBJECT = MetaObject.forObject(NullObject.class, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
private SystemMetaObject() {
// Prevent Instantiation of Static Class
}
private static class NullObject {}
//简单工厂方法 用来创建MetaObject
public static MetaObject forObject(Object object) {
return MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
}
}
可以看到,这里是直接返回的MetaObject。
MetaObject
MetaObject主要有如下方法:
getSetterNames() : 获取该class所有的setter name
getGetterNames(): 获取该class所有的getter name
hasGetter() : 此class是否有该属性的getter()
hasSetter(): 此class是否有该属性的setter()
getValue(): 获取对应属性对应的值
setValue() : 设置此属性为对应的值
从这里可以看出来,MetaObject基本包含了MyBatis需要使用的所有功能,