接上篇文章我们分享了mybatis缓存组件后,今天我们来分享一下mybatis的动态反射组件。mybatis反射模块封装得非常精妙,大家如果在项目中有POJO对象通用反射搞不定的,可以多参考一下mybatis反射组件。今天我们就来读读这块源码。

整体设计架构

mybatis源码解析 - 核心基础组件之反射_第1张图片

mybatis对POJO反射这块的设计,我的源码思路是按照如下的流程来的

mybatis源码解析 - 核心基础组件之反射_第2张图片

首先,根据POJO类实例化创建相应的对象,这步实际实现的入口在DefaultObjectFactory里面。得到实例化的对象后,通过Reflector基础工具初始化并构建对象所有相关的元数据信息和底层相关的通用API(确实封装得比较全面和严谨)。最后就是根据解析到的元数据,传入实参,进行属性的一一赋值操作并返回结果对象等的过程。

OK, 那么按照上面的思路,我们先来看看反射组件设计架构

组件设计架构mybatis源码解析 - 核心基础组件之反射_第3张图片

ObjectFactory: 产生POJO的实例对象的工厂核心接口

DefaultObjectFactory: 对象工厂的默认实现,它通过构造函数的方式创建对象的实例。有参和无参构造函数都支持,只是有参构造函数创建过程相对复杂一些(接下来会看到相应的源码);

ObjectWrapper: 对对象和对象赋值过程的包装,抽象了对象的属性,定义了一些列查询、设置和更新对象属性信息的相关API;

BeanWrapper: ObjectWrapper的默认实现,它通过MetaClass实际创建和操作对象的属性和其它信息;

ObjectWrapperFactory:  ObjectWrapper工厂,此接口目前在mybatis中没有实际起到作用;

DefaultObjectWrapperFactory: ObjectWrapperFactory默认实现,此实现类并没有实际担负创建ObjectWrapper的职责,更多只是参数的占位使用(等下源码中会看到);

ReflectorFactory: 定义Reflector创建的反射工厂接口;

DefaultReflectorFactory: 负责Reflector反射底层基础类的创建和管理;

Reflector: 反射的底层核心实现类,它是mybatis反射组件的基础;每个Reflector对象都对应一个类,在其中缓存了反射操作所需要的所有元数据信息;

MetaClass: 为了屏蔽复杂度,统一封装了ReflectorFactory和Reflector的常用操作,作为操作底层反射的入口类;

MetaObject: 作为访问mybatis反射的门面,打包和封装ObjectWrapper,ObjectWrapperFactory,Reflector,ReflectorFactory的操作,提供主要主要的业务操作接口和默认参数本身默认的实现等;

反射创建对象

mybatis源码解析 - 核心基础组件之反射_第4张图片

截图代码注释很清楚了,这里不多解释。调用方式如下:

image.png

元数据信息提取和缓存

mybatis源码解析 - 核心基础组件之反射_第5张图片

一直听说mybatis反射有个强大功能,当我们POJO对象没有实现get或set方法的时候,mybatis会帮我们自动创建这些属性的get和set方法,它是如何实现的?

mybatis源码解析 - 核心基础组件之反射_第6张图片

如上截图,我的pojo类忘了生成get/set方法,这时mybatis的处理是这样的

mybatis源码解析 - 核心基础组件之反射_第7张图片

mybatis源码解析 - 核心基础组件之反射_第8张图片

看到这里,有没有觉得mybatis反射很强大 ?

对象赋值设计

mybatis源码解析 - 核心基础组件之反射_第9张图片

那ObjectWrapper究竟在哪里创建和实例化的呢?

mybatis源码解析 - 核心基础组件之反射_第10张图片

看到了吧,实际ObjectWrapper的实例化是在MetaObject中完成的!DefaultObjectWrapperFactory实现类实际为工厂默认实现的占位,当然ObjectWrapperFactory还有另外的自定义的工厂实现, 应该是配合这些工厂实现类而创建的默认实现占位;

mybatis源码解析 - 核心基础组件之反射_第11张图片

ObjectWrapper从这里完成实例化,然后调用MetaClass对象完成赋值

mybatis源码解析 - 核心基础组件之反射_第12张图片

OK, 看到这里对mybatis三个步骤的反射设计思路应该很明了了吧 ?那么还有最后一个问题,反射这套设计是如何被mybatis其它层所集成的呢,我们接着来一鼓作气,  直捣黄龙!

mybatis源码解析 - 核心基础组件之反射_第13张图片

mybatis源码解析 - 核心基础组件之反射_第14张图片

从以上的截图可知,mybatis的反射主要用于:数据源组件、Executor执行组件(从数据库结果集到POJO对象的转换)、Cache、Session组件等地方。后面在分析mybatis运行流程的时候还会提到这些地方,这里先不每个都展开分析。


总结

OK, 以上就是mybatis反射组件的分享,其实我觉得mybatis设计思路还是相当清晰的。这里面Reflector基础类里面有的比较底层的封装,很值得分析和玩味!有兴趣的建议可以深入分析这个类,它封装得很全面也相对比较底层。今天的分享暂时就到这里,更多mybatis精彩的内容,请继续关注!