mybatis源码- 反射模块一(跟着MyBatis学反射):类级别信息的封装 (3)

MetaClass 的构造函数是私有的。

/** * MetaClass 构造函数 */ private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) { this.reflectorFactory = reflectorFactory; this.reflector = reflectorFactory.findForClass(type); }

但是, 其提供了两个创建的方法。 这两个方法也是通过该方法进行创建对象的。 该方法通过 Class 对象进行了 Reflector 对象的创建, 并赋值给成员变量。

/** * 跟上面的是一样的 */ public static MetaClass forClass(Class<?> type, ReflectorFactory reflectorFactory) { return new MetaClass(type, reflectorFactory); }

通过属性进行创建

/** * 通过属性名称, 获取属性的 MetaClass */ public MetaClass metaClassForProperty(String name) { Class<?> propType = reflector.getGetterType(name); return MetaClass.forClass(propType, reflectorFactory); } 4.3 方法

该类中, 最重要的方法是:

/** * 解析属性表达式 * 会去寻找reflector中是否有对应的的属性 * @param name * @param builder * @return */ private StringBuilder buildProperty(String name, StringBuilder builder) { // 解析属性表达式 PropertyTokenizer prop = new PropertyTokenizer(name); // 是否有子表达式 if (prop.hasNext()) { // 查找对应的属性 String propertyName = reflector.findPropertyName(prop.getName()); if (propertyName != null) { // 追加属性名 builder.append(propertyName); builder.append("."); // 创建对应的 MetaClass 对象 MetaClass metaProp = metaClassForProperty(propertyName); // 解析子表达式, 递归 metaProp.buildProperty(prop.getChildren(), builder); } } else { // 根据名称查找属性 String propertyName = reflector.findPropertyName(name); if (propertyName != null) { builder.append(propertyName); } } return builder; }

理解了这个方法(递归, 该类中有很多类似的), 就可以很好的对这个类进行理解, 以查找(richType.richProperty)为例:

通过 PropertyTokenizer 对表达式进行解析, 得到当前的 name=richType, children=richProperty

从 reflector 中查找该 richType 属性

将 richType 添加到 builder 中

使用 metaClassForProperty 创建 richType 的 MetaClass。

递归调用自身来处理子表达式

退出的条件就是没有子表达式。 这个就是为了, 我们类中有成员变量是类, 我们可以通过其找到他们的所有类及其属性。

注意, 在此过程中, ReflectorFactory 一直是同一个, 而其内部缓存了多个 Reflector 对象。

5 总结

类的关系:

关系

Reflector 实现了实体类元信息的封装, 但对类中的成员变量是类的情况没有进行处理。 而 MetaClass 通过 ReflectorFactory 类型的成员变量, 实现了实体类中成员变量是类情况的处理。从而结合属性工具类实现了对复杂表达式的处理。

一起学 mybatis

你想不想来学习 mybatis? 学习其使用和源码呢?那么, 在博客园关注我吧!!

我自己打算把这个源码系列更新完毕, 同时会更新相应的注释。快去我的github star 吧!!

项目

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwdzy.html