最近在看MyBatis源码,发现MyBatis底层有一个自己封装的工具类——Reflector,该类位于org.apache.ibatis.reflection包下。MyBatis在解析数据库查询返回数据的时候,会使用到我们配置的映射类型,它在底层实现的时候,就使用到了该工具类。
在阅读了这个工具类方法的源码之后,特作简单小节。该工具类就是一个反射方法的封装体,能够传入指定的Class类,然后解析出类中相关的数据信息。
文章目录
- 一、使用分享
- 1、方法测试
- 2、简单使用
- 二、源码分享
- 1、addFields
- 2、addGetMethods
- 3、源码小细节
一、使用分享
1、方法测试
实体类
测试方法:
测试结果:
2、简单使用
目前还不知道这个工具类如何能够在实际开发中如何使用,就当学习长见识了,下面是自己的一个测试小Demo——给指定对象的id属性赋值(用起来和反射不能说是相似,只能说是一模一样)
二、源码分享
1、addFields
如果你仔细看了我上面的User类,你就会发现它的flag属性是没有get和set方法的。但是如果你自己去测试flag方法是否含有get和set方法的时候,他返回的是true
原因就是,这个工具类会去遍历目标类的所有的成员,判断该变量是否符合相关规则,如果符合就会默认对该变量添加一个get和set方法,对应的源码方法,在addFields方法里面。下图是这个工具类的构造方法,调试参数值就从这里往下看
构造方法,数据初始化的地方,即入口
主要的处理逻辑就在该方法中,对于没有get和set的方法,在满足条件的基础上,会默认添加get和set方法
2、addGetMethods
由于该类代码比较简单,我又找了一个比较典型的方法,其他的细节请自行参考该类代码
对方法进行过滤,然后添加到对应的集合中
这里的操作是,构建一个新的数据集合,用来存放key-value(成员属性名字-候选方法列表)
对候选方法进行逻辑校验,最终选择一个方法
将候选的方法,添加到对应的map中
3、源码小细节
其实我个人觉得这个功能很鸡肋,它在获取get方法的时候,会把is方法也当作get方法处理
查看源码,我发现,如果我在一个类中即添加了isId方法,又添加一个getId方法,那么最终只会注册进一个方法,如下图的测试。确实这是正常的,由上面的分析可以得出,如果有两个候选方法,那么我们就可以只会添加其中一个,然后模糊标志位标记为true,最终创建的对象也是一个模糊对象。所以下面的方法执行会报错。
但是,如果我们去掉get方法,只使用is方法呢?
于是我又对Usesr类进行了修改,去掉get方法
测试结果居然是is方法当作了get方法处理。emmm…也许是MyBatis的作者们是出于什么其他想法才这样设计吧。
分享完毕,如果对你有帮助,期待你的点赞与收藏。