MetaObject是Mybatis中的反射工具类,其位于Mybatis源码包中的org.apache.ibatis.reflection。从MetaObject的命名和所处的位置不难看出,该类主要的工作就是获取和设置对象的属性值。
@Data
public class Robot{
private String name;
}
Robot robot = new Robot();
// 使用SystemMetaObject类的静态方法forObject()构造MetaObject
MetaObject metaObject = SystemMetaObject.forObject(robot);
metaObject.setValue("name", "机器人0001");
Object value = metaObject.getValue("name");
从上述示例代码可以看出,MetaObject类是使用SystemMetaObject类的静态方法forObject()来完成构造的,那么为什么要使用SystemMetaObject类的静态方法forObject()来构造呐?这里就不得不从MetaObject类的构造方法说起了。
构造方法
MetaObject构造方法的源代码如下:
/**
* @param object 原始对象
* @param objectFactory 对象工厂
* @param objectWrapperFactory 对象包装工厂
* @param reflectorFactory 反射工厂
*/
private MetaObject(
Object object,
ObjectFactory objectFactory,
ObjectWrapperFactory objectWrapperFactory,
ReflectorFactory reflectorFactory) {
this.originalObject = object;
this.objectFactory = objectFactory;
this.objectWrapperFactory = objectWrapperFactory;
this.reflectorFactory = reflectorFactory;
if (object instanceof ObjectWrapper) {
this.objectWrapper = (ObjectWrapper) object;
} else if (objectWrapperFactory.hasWrapperFor(object)) {
this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);
} else if (object instanceof Map) {
this.objectWrapper = new MapWrapper(this, (Map) object);
} else if (object instanceof Collection) {
this.objectWrapper = new CollectionWrapper(this, (Collection) object);
} else {
this.objectWrapper = new BeanWrapper(this, object);
}
}
从源代码可以看出MetaObject类的构造方法被改为了private私有域,这也是不能直接通过new MetaObject()来构造MetaObject对象的主要原因。通过观察MetaObject构造方法可以看出,如果想要构造一个MetaObject对象就除了提供想要操作的原始object以外,同时还要提供ObjectFactory、ObjectWrapperFactory和ReflectorFactory三个同样位于org.apache.ibatis.reflection包下的反射操作接口。
- ObjectFactory
ObjectFactory位于Mybatis源代码org.apache.ibatis.reflection.factory包中,从所处的包和命名不难看出,该接口的主要职责就是用来创建所需类的对象。其主要实现类DefaultObjectFactory实现了所需的所有方法。
- ObjectWrapperFactory
ObjectWrapperFactory位于Mybaits源代码org.apache.ibatis.reflection.wrapper包中,该接口主要的职责就是将某个对象包装成ObjectWrapper对象,其主要实现类DefaultObjectWrapperFactory提供了支持。
- ReflectorFactory
ReflectorFactory位于Mybatis源代码org.apache.ibatis.reflection包中,该接口的主要职责就是对目标对象进行反射操作提供能力,其主要实现类DefaultReflectorFactory提供了支持。
从MetaObject构造方法的源代码来看,其除了对Object object、ObjectFactory objectFactory、ObjectWrapperFactory objectWrapperFactory和ReflectorFactory reflectorFactory这个属性进行赋值以外,还通过判断目标对象object的对象属性来构造ObjectWrapper对象来作为整个反射操作后的承载。在构造ObjectWrapper对象的过程中,同时使用到了之前已经赋值好的objectFactory、objectWrapperFactory和reflectorFactory对象。
SystemMetaObject
至此再来看下SystemMetaObject类中的静态方法forObject构造MetaObject对象的细节,SystemMetaObject源代码中定义了两个常量分别对应ObjectFactory和ObjectWrapperFactor,最终这两个常量会用于调用MetaObject.forObject()方法来构造MetaObject对象。
从SystemMetaObject类中的静态方法forObject得出,最终还是调用了MetaObject.forObject()方法来构造MetaObject对象
public final class SystemMetaObject {
public static final ObjectFactory DEFAULT_OBJECT_FACTORY =
new DefaultObjectFactory();
public static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY =
new DefaultObjectWrapperFactory();
public static final MetaObject NULL_META_OBJECT = MetaObject.forObject(
new NullObject(), DEFAULT_OBJECT_FACTORY,
DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
private SystemMetaObject() {
// Prevent Instantiation of Static Class
}
private static class NullObject {
}
public static MetaObject forObject(Object object) {
return MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY,
DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
}
}
MetaObject操作对象
上述已经明白了MetaObject对象是如何构造而来的,并且从构造方法我们不难看出MetaObject类使用了组合模式,配合originalObject、objectWrapper、objectFactory、objectWrapperFactory和reflectorFactory五个属性对象来使得原始对象完成反射操作。
- Object getValue(String name),获取目标对象中某个属性对应的值。
- void setValue(String name, Object value),将值value赋值到目标对象的name属性中。
- boolean hasSetter(String name),判断目标对象name属相是否有setter方法。
- boolean hasGetter(String name),判断目标对象name属相是否有getter方法。