MyBatis 原理浅析 2 ——配置解析

前言

在前文《MyBatis 原理浅析——基本原理》一文中,简要分析了 MyBatis 的技术原理,主要是 SqlSession 和 Mapper 的相关实现原理。本文重点分析 MyBatis 的配置解析过程,从 XML 文件提取配置到 Configuration 类。

XML解析涉及到的类

XML 解析主要涉及以下几个类:XMLConfigBuilder、XMLMapperBuilder、BaseBuilder、XNode、Configuration、XPathParser 和Configuration 中的配置类。各个类型的关系可以简单用下图描述。在 SqlSessionFactoryBuilder 类中调用方法解析 XML 时使用的是XMLConfigBuilder 类,XMLConfigBuilder 类的 parse 方法是 XML 解析的入口,解析完成后返回配置类型Configuration。BaseBuilder 类是抽象类,提供了 typeAlias、typeHandler 配置的处理方法,也是XMLConfigBuilder 类和XMLMapperBuilder类的父类。XNode 类用于存储解析过程中遇到的节点,XPathParser 类封装了 XPath 相关的操作,如 XML文件的载入、节点的解析等。Configuration 类存储了解析出来的所有属性。

MyBatis 原理浅析 2 ——配置解析_第1张图片

XML 解析准备阶段

XML 文件的解析通过在SqlSessionFactoryBuilder 类中创建XMLConfigBuilder 类并调用其 parse 方法开始。

MyBatis 原理浅析 2 ——配置解析_第2张图片

在XMLConfigBuilder 初始化时,会创建XPathParser 类的实例,然后创建Configuration 类的实例,保存各个参数以供后续使用。

MyBatis 原理浅析 2 ——配置解析_第3张图片

在XPathParser 类的初始化过程中,会创建 XPath 实例,然后读入 XML 文件创建 Document 对象,完成 XML 文件解析的准备工作。

MyBatis 原理浅析 2 ——配置解析_第4张图片

XML 配置解析过程

XML 配置解析是从XMLConfigBuilder 的parse() 方法开始的。在 parse() 方法中,首先判断是否已经解析过,如果重复解析则抛出异常,然后解析出 XML 文件的根节点 configuration,再从根节点中依次解析出 properties、settings、typeAliases、plugins、objectFactory、objectWrapperFactory、reflectorFactory、environments、databaseIdProvider、typeHandlers、mappers节点的内容,解析完成后返回configuration 对象。

MyBatis 原理浅析 2 ——配置解析_第5张图片

解析过程可以分为以下几步:

1、解析 properties :读取 XML 中的名称键值对并保存,如果引用了 properties 文件或传入了 properties 配置,则会用新的 properties 值替换 XML 中的配置。

2、解析 settings:按照 Properties 类型存储。

3、解析 typeAliases:typeAliases 定义了类的别名,解析后需要根据 type 的值加载相应的 class,并注册到 typeAliasRegistry 中。

4、解析 plugins:加载 Interceptor 实现类,创建对象,并存入 configuration 中。

5、解析 objectFactory:加载 ObjectFactory 实现类,创建对象,并存入 configuration 中。

6、解析 objectWrapperFactory:加载 ObjectWrapperFactory 实现类,创建对象,并存入 configuration 中。

7、解析 reflectorFactory:加载 ReflectorFactory 实现类,创建对象,并存入 configuration 中。

8、解析 environments:根据配置的默认环境 ID,加载环境配置,创建 Environment 对象,并存入 configuration 中。Environment 对象包含了数据源和事务管理器对象。

9、解析 databaseIdProvider:加载 DatabaseIdProvider 实现类,读取属性配置,创建对象,获取数据源的 databaseId 并存入 configuration。

10、解析 typeHandlers:解析属性配置,加载实现类,创建对象,并注册到 typeHandlerRegistry 中。

11、解析 mappers:解析 mapper 节点,如果引用了 XML 文件则载入文件并创建 XMLMapperBuilder 对象进行解析,如果引用了包或类则添加到 configuration 中。注册 Mapper 到 MapperRegistry 时,会创建 Mapper 接口的代理实现工厂 MapperProxyFactory,扫描 Mapper 接口的注解并存入configuration 。

Mapper 文件的解析

mapper XML 文件的解析在XMLMapperBuilder 中实现。与XMLConfigBuilder 一样,XMLMapperBuilder 初始化时也会创建XPathParser 类的实例,但会使用参数传入的 configuration。

XML 文件的解析是在 parse 方法中完成的。首先判断是否已经加载过,如果没有加载过则获取 XML 的根节点 mapper 并开始解析,解析完成后根据命名空间的配置加载相应的 Mapper 接口并添加到configuration 中,最后加载未完成加载的 ResultMap、CacheRef 和 Statement。

MyBatis 原理浅析 2 ——配置解析_第6张图片

configurationElement 方法实现了对 mapper 子节点的解析,如下所示,读取了 namespace、cache-ref、cache、parameterMap、resultMap、sql、select、insert、update、delete 等节点和属性。如果引用的类型不在此 XML 中,并且配置中也获取不到,则会加入未完成列表,在解析下个 XML 文件时再次尝试加载。

MyBatis 原理浅析 2 ——配置解析_第7张图片

mapper 文件的解析细节比较复杂,后文再深入分析。

每周 3 篇学习笔记或技术总结,面向有一定基础的 Java 程序员,内容涉及 Java 进阶、虚拟机、MySQL、NoSQL、分布式计算、开源框架等多个领域。关注作者或微信公众号 backend-develop 第一时间获取最新内容。

你可能感兴趣的:(MyBatis 原理浅析 2 ——配置解析)