type
status
date
slug
summary
tags
category
icon
password

1.反射模块
MyBatis在进行参数处理、结果集映射等操作时会使用到大量的反射操作,Java中的反射功能虽然强大,但是代码编写起来比较复杂且容易出错,为了简化反射操作的相关代码,MyBatis提供了专门的反射模块,该模块位于org.apache.ibatis.reflection包下,它对常见的反射操作做了进一步的封装,提供了更加简洁方便的反射API。

1.1 Reflector
Reflector是反射模块的基础,每个Reflector对象都对应一个类,在Reflector中缓存了反射需要使用的类的元信息
1.1.1 属性
首先来看下Reflector中提供的相关属性的含义
1.1.2 构造方法
在Reflector的构造器中会完成相关的属性的初始化操作
反射我们也可以在项目中我们直接拿来使用,定义一个普通的Bean对象。
1.1.3 公共的API方法
Reflector中提供的公共的API方法
方法名称 | 作用 |
getType | 获取Reflector表示的Class |
getDefaultConstructor | 获取默认的构造器 |
hasDefaultConstructor | 判断是否有默认的构造器 |
getSetInvoker | 根据属性名称获取对应的Invoker 对象 |
getGetInvoker | 根据属性名称获取对应的Invoker对象 |
getSetterType | 获取属性对应的类型 比如:String name; // getSetterType("name") --> java.lang.String |
getGetterType | 与上面是对应的 |
getGetablePropertyNames | 获取所有的可读属性名称的集合 |
getSetablePropertyNames | 获取所有的可写属性名称的集合 |
hasSetter | 判断是否具有某个可写的属性 |
hasGetter | 判断是否具有某个可读的属性 |
findPropertyName | 根据名称查找属性 |
了解了Reflector对象的基本信息后我们需要如何来获取Reflector对象呢?在MyBatis中给我们提供了一个ReflectorFactory工厂对象。所以我们先来简单了解下ReflectorFactory对象,当然你也可以直接new 出来,像上面的案例一样;
1.2 ReflectorFactory
1.2.1 ReflectorFactory接口的定义
具体实现
MyBatis只为该接口提供了DefaultReflectorFactory这一个实现类。他与Reflector的关系如下:

DefaultReflectorFactory中的实现,代码比较简单
1.3 Invoker
针对于Class中Field和Method的调用,在MyBatis中封装了Invoker对象来统一处理(有使用到适配器模式)
1.3.1 接口说明
对应的实现类

实验代码
测试代码
1.4 MetaClass
在Reflector中可以针对普通的属性操作,但是如果出现了比较复杂的属性,比如 private Person person; 这种,我们要查找的表达式 person.userName.针对这种表达式的处理,这时就可以通过MetaClass来处理了。我们来看看主要的属性和构造方法
实验:
Bean对象
测试
1.5 MetaObject
通过MetaObject对象解析复杂的表达式来对提供的对象进行操作。具体的通过案例来演示会更直观些
1.6 反射模块应用
1.6.1 SqlSessionFactory
创建SqlSessionFactory操作的时候会完成Configuration对象的创建,而在Configuration中默认定义的ReflectorFactory的实现就是DefaultReflectorFactory对象
protected ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
然后在解析全局配置文件的代码中,给用户提供了ReflectorFactory的扩展,也就是我们在全局配置文件中可以通过reflectorFactory标签来使用我们自定义的ReflectorFactory
1.6.2 SqlSession 无
1.6.3 Mapper 无
1.6.4 执行SQL
在Statement获取结果集后,在做结果集映射的使用有使用到,在DefaultResultSetHandler的createResultObject方法中。

然后在DefaultResultSetHandler的getRowValue方法中在做自动映射的时候

继续,在 createAutomaticMappings

当然还有很多其他的地方在使用反射模块来完成的相关操作,这些可自行查阅
- Author:atsuc
- URL:https://blog.atsuc.cn/article/blog-source-008
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!