MetaClass同MetaObject一样,是Mybatis中的反射工具类。其位于Mybatis源码包中的org.apache.ibatis.reflection。从该类的命名不难看出,这个类主要的职责就是获取目标类相关信息。MetaClass与MetaObject二者主要区别在于:MetaObject用于获取和设置对象的属性值,MetaClass则用于获取类的相关信息。换言之,MetaObject主要负责操作目标对象对应的属性值,MetaClass主要负责操作目标对象对应的类的一些信息(如获取构造方法,getter方法的属性名)。
@Data
public class Robot{
private String name;
}
MetaClass metaClass = MetaClass.forClass(
Robot.class, new DefaultReflectorFactory());
// 获取有getter方法的属性名
String[] names = metaClass.getGetterNames();
// 是否有默认的构造方法
metaClass.hasDefaultConstructor();
从上述示例代码可以看出,使用MetaClass.forClass方法构造MetaClass对象时,在需要传入目标对象的基础上,还需要传入一个实现ReflectorFactory接口的DefaultReflectorFactory反射工厂。接下来将进入MetaClass.forClass方法的源码细则。
MetaClass的构造
private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) {
this.reflectorFactory = reflectorFactory;
this.reflector = reflectorFactory.findForClass(type);
}
/**
* @param type 原始对象
* @param reflectorFactory 反射工厂
*/
public static MetaClass forClass(
Class<?> type, ReflectorFactory reflectorFactory) {
return new MetaClass(type, reflectorFactory);
}
从Mybatis源代码来看,MetaClass同样把自己的构造方法设置为了private私有域,所以如果想要构造MetaClass对象,就只能使用MetaClass类提供的forClass方法来构造。forClass方法有两个参数,一个是表示要操作对象的type,一个是用于反射操作的reflectorFactory。forClass在拿到这两个参数之后,再去调用MetaClass对象的构造方法来设置属性值和生成一个Reflector对象,并赋值给MetaClass中对应的reflector属性。
Reflector对象是用于缓存当前目标对象中对应的类定义信息,如构造方法或者Setter方法对应的所有属性名等类中的一些细节信息,都将在构造MetaClass对象的时候读取并放入reflector属性。
MetaClass操作类
MetaClass提供了许多方法来获取Java类的基本信息,其中包括类中所有的Getter方法对应的属性名称和是否有默认的构造方法等信息,甚至可以通过MetaClass获取Getter/Setter方法对应的Invoker对象,
- String[] getSetterNames(),获取类中所有的Setter方法对应的属性名。
- String[] getGetterNames(),获取类中所有的Getter方法对应的属性名。
- Invoker getGetInvoker(String name),获取name属性对应的Get Invoker对象。
- Invoker getSetInvoker(String name),获取name属性对应Set Invoker对象。
- boolean hasDefaultConstructor(),判断类是否有默认的构造方法。