Mybatis源码分析-3.开始配置解析

XMLConfigBuilder

根据上一节内容我们已经知道了,XML配置文件的解析全部是通过XMLConfigBuilder进行完成的,该类的类继承结构如下:

在这里插入图片描述

其中BaseBuilder提供了一个配置解析器所需要的大部分工具方法,以及通用的变量、操作这些通用变量的方法。通用的变量分别如下:

  1. Configuration:configuration,用于存储解析过程中用于担当解析结果的Configuration对象
  2. TypeAliasRegistry: typeAliasRegistry,用于存储类型别名的注册表
  3. TypeHandlerRegistry: typeHandlerRegistry,用于存储类型处理器的注册表

对于一个配置解析器来说,保存结果的对象肯定是必须的,剩下两个注册表分别是别名和类型处理器,这到底是谁通用的呢。我们考察BaseBuilder的子类,类图如下:

在这里插入图片描述

可以看到,BaseBuilder有7个子类,分别是:

  1. XMLConfigBuilder:Mybatis xml配置解析器
  2. XMLScriptBuilder:Mybatis 动态SQL标签解析器
  3. XMLMapperBuilder:Mybatis mapper标签配置解析器
  4. SqlSourceBuilder:Mybatis ParameterMap标签解析器
  5. XMLStatementBuiler: Mybatis SQL语句解析器,解析insert、update、select标签
  6. MapperBuilderAssistant:Mapper解析时的辅助缓存
  7. ParameterMappingTokenHandler:parameterMapping的解析工具

由于别名注册表和类型处理器是除了配置文件外每个Mapper文件都要用的,因此,就把它放在了BaseBuilder中。除了XMLConfigBuilder以外所有的其他Builder都是为<mapper>服务的。

所以我们可以根据配置文件来对代码进行分析,首先分析Mybatis的基本配置解析,然后再分析<mapper>标签的配置解析。

首先让我们分析XMLConfigBuilder的解析Mybatis配置的逻辑:也就是XMLConfigBuilderparse()方法:

public Configuration parse() {
    // 处理重复解析问题
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    // 解析configuration标签
    parseConfiguration(parser.evalNode("/configuration"));
    // 返回解析结果
    return configuration;
}

根据Mybatis文档可知,Mybatis配置文档层级结构如下:

  • configuration(配置)
    • properties(属性)
    • settings(设置)
    • typeAliases(类型别名)
    • typeHandlers(类型处理器)
    • objectFactory(对象工厂)
    • plugins(插件)
    • environments(环境配置)
      • environment(环境变量)
        • transactionManager(事务管理器)
        • dataSource(数据源)
    • databaseIdProvider(数据库厂商标识)
    • mappers(映射器)

所以要从根节点configuration开始解析,具体解析逻辑在parseConfiguration(XNode root)方法中,该方法代码如下:

private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      // 解析properties标签
      propertiesElement(root.evalNode("properties"));
      // 解析settings标签
      // 该方法就是将<settings>标签中声明的key-value值转化为Properties格式,然后统一进行设置
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      // 加载虚拟文件系统,毕竟是要从文件系统读取配置
      // 此处可以忽略
      loadCustomVfs(settings);
      // 解析typeAliases标签
      // 将别名存入到TypeAliasRegistry中
      typeAliasesElement(root.evalNode("typeAliases"));
      // 解析plugins标签
      pluginElement(root.evalNode("plugins"));
      // 解析objectFactory标签
      // 对于Mybatis来说,返回结果对象都由ObjectFactory生成,这里就对其进行配置
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      settingsElement(settings);
      // 解析environments标签
      environmentsElement(root.evalNode("environments"));
      // 解析databaseIdProvier标签
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      // 解析typeHandlers 标签
      typeHandlerElement(root.evalNode("typeHandlers"));
      // 解析mappers标签
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
}

事实上根据方法名我们就可以知道哪个方法用于解析哪个标签。由于笔者时间有限,接下来会对几个常用标签的解析方法进行详细说明,其中包括:

  1. 插件标签
  2. mapper标签

更多的标签将在后续进行补充。接下来让我们先去查看<plugin>标签的解析过程吧!

下一节:Mybatis源码解析-4.插件配置解析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值