mybatis解析主配置文件之解析properties标签

发布时间 2023-12-01 21:56:08作者: 神行诸葛

mybatis在启动的时候会去解析主配置文件,这些配置文件的数据会生成一个mybatis重量级对象,也是全局唯一对象-Configuration。这个对象就存储着你写的配置文件的信息,甚至包括你的sql映射文件信息都有。可见解析这个主配置文件是多么的复杂。

所以我们要抽丝剥茧。一个个来看。好在mybatis解析主配置文件的逻辑还是比较清晰的。我们可以先大致看看代码

XMLConfigBuilder
/**
   * root就是一开始解析xml文件的根节点configuration
   * @param root
   */
private void parseConfiguration(XNode root) {
    try {
      //解析properties标签
      propertiesElement(root.evalNode("properties"));
      //解析settings标签
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      //这两个跟日志有关
      loadCustomVfs(settings);
      loadCustomLogImpl(settings);
      //解析别名
      typeAliasesElement(root.evalNode("typeAliases"));
      //解析插件
      pluginElement(root.evalNode("plugins"));
      //下面三个不怎么用
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      //把settings标签解析出来的对象填充到Configuration内部
      settingsElement(settings);
      //解析environments 很重要,这里就可以获取连接
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      //解析类型转换器
      typeHandlerElement(root.evalNode("typeHandlers"));
      //解析mapper标签 很重要,这里面对sql语句进行解析
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }

我们看到,第一行就是解析properties标签,这个标签在我们使用mybatis的时候看着好像没用过。但是还是有点用的。

<configuration>
    <properties resource="log4j.properties" url="https://www.baidu.com">
        <property name="a" value="b"/>
        <property name="c" value="d"/>
    </properties>

properties标签有两个属性,一个resource,一个url.这两个属性不能同时存在。resource是从本地获取文件,而url显然是从网络上获取。内部的property标签的name和value可以随便写。我们还是直接卡代码就清晰了

/**
   * 解析properties标签
   * @param context properties 标签
   * @throws Exception
   */
  private void propertiesElement(XNode context) throws Exception {
    if (context != null) {
      //获取所有property标签
      Properties defaults = context.getChildrenAsProperties();
      //获取properties的两个属性值
      String resource = context.getStringAttribute("resource");
      String url = context.getStringAttribute("url");
      //两个同时存在就报错
      if (resource != null && url != null) {
        throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference.  Please specify one or the other.");
      }
      if (resource != null) {
        //Resources.getResourceAsProperties(resource)将本地文件变成流在转成Properties对象
        defaults.putAll(Resources.getResourceAsProperties(resource));
      } else if (url != null) {
        //Resources.getUrlAsProperties(url)将网络文件变成流在转成Properties对象
        defaults.putAll(Resources.getUrlAsProperties(url));
      }
      //这个configuration就是存储我们的配置信息
      Properties vars = configuration.getVariables();
      //默认是null,这个为null是前面一些代码导致的,本来在configuration是有个空 Properties 的
      if (vars != null) {
        defaults.putAll(vars);
      }
      //把生成的Properties设置给xml的解析器对象,这个是为了后面解析的时候可以直接使用,略过
      parser.setVariables(defaults);
      //这里就是将解析出来的properties设置到configuration中
      configuration.setVariables(defaults);
    }
  }

这段代码难度并不大。主要就是解析properties标签生成Properties对象,然后设置到configuration中。要么是用本地文件生成,要么是用网络上的文件生成。不难理解。至于后面什么作用,还是要看后面解析主配置文件的逻辑。

好的,告一段落。