基础支持层位于MyBatis整体架构的最底层 , 支撑着MyBatis的核心处理层 , 是整个框架的基石 。基础支持层中封装了多个较为通用的、独立的模块 。不仅仅为MyBatis提供基础支撑 , 也可以在合适的场景中直接复用 。
文章插图
反射模块详解 MyBatis在进行参数处理、结果集映射等操作时会使用到大量的反射操作 , JAVA中的反射功能虽然强大 , 但是代码编写起来比较复杂且容易出错 , 为了简化反射操作的相关代码 , MyBatis提供了专门的反射模块 , 该模块位于
org.Apache.ibatis.reflection包下 , 它对常见的反射操作做了进一步的封装 , 提供了更加简洁方便的反射API 。
文章插图
1 ReflectorReflector是反射模块的基础 , 每个Reflector对象都对应一个类 , 在Reflector中缓存了反射需要使用的类的元信息
1.1 属性
? 首先来看下Reflector中提供的相关属性的含义
// 对应的Class 类型private final Class<?> type;// 可读属性的名称集合 可读属性就是存在 getter方法的属性 , 初始值为nullprivate final String[] readablePropertyNames;// 可写属性的名称集合 可写属性就是存在 setter方法的属性 , 初始值为nullprivate final String[] writablePropertyNames;// 记录了属性相应的setter方法 , key是属性名称 , value是Invoker方法// 它是对setter方法对应Method对象的封装private final Map<String, Invoker> setMethods = new HashMap<>();// 属性相应的getter方法private final Map<String, Invoker> getMethods = new HashMap<>();// 记录了相应setter方法的参数类型 , key是属性名称 value是setter方法的参数类型private final Map<String, Class<?>> setTypes = new HashMap<>();// 和上面的对应private final Map<String, Class<?>> getTypes = new HashMap<>();// 记录了默认的构造方法private Constructor<?> defaultConstructor;// 记录了所有属性名称的集合private Map<String, String> caseInsensitivePropertyMap = new HashMap<>();
1.2 构造方法? 在Reflector的构造器中会完成相关的属性的初始化操作
// 解析指定的Class类型 并填充上述的集合信息public Reflector(Class<?> clazz) {type = clazz; // 初始化 type字段addDefaultConstructor(clazz);// 设置默认的构造方法addGetMethods(clazz);// 获取getter方法addSetMethods(clazz); // 获取setter方法addFields(clazz); // 处理没有getter/setter方法的字段// 初始化 可读属性名称集合readablePropertyNames = getMethods.keySet().toArray(new String[0]);// 初始化 可写属性名称集合writablePropertyNames = setMethods.keySet().toArray(new String[0]);// caseInsensitivePropertyMap记录了所有的可读和可写属性的名称 也就是记录了所有的属性名称for (String propName : readablePropertyNames) {// 属性名称转大写caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);}for (String propName : writablePropertyNames) {// 属性名称转大写caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);}}
反射我们也可以在项目中我们直接拿来使用,定义一个普通的Bean对象 。/** * 反射工具箱 *测试用例 */public class Person {private Integer id;private String name;public Person(Integer id) {this.id = id;}public Person(Integer id, String name) {this.id = id;this.name = name;}}
测试文章插图
1.3 公共的API方法
然后我们可以看看Reflector中提供的公共的API方法
文章插图
了解了Reflector对象的基本信息后我们需要如何来获取Reflector对象呢?在MyBatis中给我们提供了一个ReflectorFactory工厂对象 。所以我们先来简单了解下ReflectorFactory对象,当然你也可以直接new 出来 , 像上面的案例一样
2 ReflectorFactory ReflectorFactory接口主要实现了对Reflector对象的创建和缓存 。
2.1 ReflectorFactory接口的定义
? 接口的定义如下
public interface ReflectorFactory {// 检测该ReflectorFactory是否缓存了Reflector对象boolean isClassCacheEnabled();// 设置是否缓存Reflector对象void setClassCacheEnabled(boolean classCacheEnabled);// 创建指定了Class的Reflector对象Reflector findForClass(Class<?> type);}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 一篇文章带你搞懂Python中的类
- 软件测试知识点3大场景带你了解单元测试
- 彻底搞懂虚拟地址翻译为物理地址的过程
- 彻底搞懂虚拟内存,虚拟地址,虚拟地址空间
- 小青柑茶多少钱盒,小青柑是什么茶带你全面了解小青柑
- 如何彻底搞懂Mysql事务原理
- 桃花治便秘最彻底的偏方法,桃花的功效与作用
- 帮你彻底搞懂 JS 中的 prototype、__proto__与constructor
- 15张图表带你速览2021人工智能最新趋势
- 电池|一季度动力电池装机量排行榜:宁德时代彻底无敌 以一打十