Mybatis源码深入理解二——配置解析

97 阅读2分钟

前言

不论是SpringBoot整合Mybatis,亦或者是我们单独使用Mybatis,我们在使用Mybatis的时候都需要首先进行配置。

配置可以让用户根据自己的实际情况来实现自己的功能。对所有框架来说,需要做的第一步都是将用户编写的配置读取解析并存储起来,为后续业务做支撑。

这里我们以Mybatis的全局配置文件mybatis-config.xml配置为例,展开该框架是如何解析XML文件并初始化相关配置内容的。

搭建好本地源码环境,项目结构如下:

图片.png

案例中使用的全局配置文件如下: mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <settings>
    <setting name="cacheEnabled" value="true"/>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
  </settings>
  <typeAliases>
    <package name="org.apache.ibatis.test.domain"/>
  </typeAliases>

  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test"/>
        <property name="username" value="root"/>
        <property name="password" value="****"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <!--        <package name="org.apache.ibatis.test.mapper" ></package>-->
    <mapper resource="org/apache/ibatis/test/mapper/xml/PeopleMapper.xml"/>
  </mappers>

</configuration>

解析流程

我们从第一步开始
进入build方法,打一个断点,运行代码。 image.png

进入到调用的build方法,发现创建了一个配置构建器,进入到parse()方法中。 图片.png

这个是真正的解析方法,本质上就是解析xml配置文件中的各种配置,每种类型大家通过名字应该能够看出来。 我们挑几个比较重要的解析方法来查看。

image.png

解析settings

图片.png

解析typeAliases

进入到typeAliasesElement()方法中。 图片.png

通过包名,反射获取到了该包下的所有类,然后遍历,依次为其添加别名。 图片.png

继续进入registerAlias()

图片.png

发现,最终所有的别名配置都放入到了一个Map中。key就是别名,value是对应的Class对象。 图片.png

解析environment

进入到 environmentsElement() 图片.png

数据源的配置有三种类型:POOLED、UNPOOLED、JNDI。通过类型从别名的Map中获取到对应的数据源Class对象,然后通过反射创建该对象。 图片.png

解析mapper

进入到mapperElement() 图片.png

parse()方法中有核心的三个步骤 图片.png

1. 将XML中的每一个语句解析生成MappedStatement对象

点击进入该方法 图片.png

图片.png

图片.png

核心是该方法最后一行

图片.png

继续点击进入该方法,在方法后面发现创建了一个MappedStatement对象,并添加到Configuration中。

图片.png

2. 将xml类文件的全路径添加到已加载资源中

点进这个方法一看,就是一个add方法,loadedResource也只是一个Set集合而已,用于标记一下该资源已经处理过了。 图片.png

图片.png

3. 创建Mapper和XML文件的对应关系

图片.png

获取SqlSessionFactory

进入到Build() image.png

发现直接new了一个DefaultSqlSessionFactory image.png

创建SqlSession

工厂已经创建好了,进入到openSession() image.png 一直进入方法,来到openSessionFromDataSource()

image.png

总结

  1. 该阶段创建了数据源DataSource、事务管理器,完成了别名相关映射、Sql语句解析、mapper解析等过程。
  2. 解析阶段所有的配置将会被存储Configuration这个类中,在后续的过程中会一直使用到其中的配置。所以configuration是一个非常非常重要的全局类。