mybatis-3.4.6 顶层配置解析

系列

  • mybatis-3.4.6 配置介绍
  • mybatis-3.4.6 顶层配置解析
  • mybatis-3.4.6 子配置解析
  • mybatis-3.4.6 mapper解析
  • mybatis-3.4.6 SQL执行流程
  • mybatis-3.4.6 SqlSession执行过程
  • mybatis-3.4.6 缓存介绍
  • mybatis-3.4.6 自增主键
  • mybatis-3.4.6 foreach 自增主键
  • mybatis-3.4.6 事务管理


开篇

  • 这个系列是基于mybatis-3.4.6版本的源码解析,这篇文章主要分析mybatis的底层配置解析流程。
  • SqlSessionFactory是通过SqlSessionFactoryBuilder工厂类创建的,而不是直接使用构造器
reader = Resources.getResourceAsReader(resouce);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);


顶层配置解析流程

mybatis-3.4.6 顶层配置解析_第1张图片
配置解析流程
  • 配置解析的流程如上图,核心在于SqlSessionFactoryBuilder和XMLConfigBuilder。
  • parseConfiguration负责解析configuration.xml生成Configuration对象。


SqlSessionFactoryBuilder

public class SqlSessionFactoryBuilder {

  public SqlSessionFactory build(Reader reader) {
    return build(reader, null, null);
  }

  public SqlSessionFactory build(Reader reader, String environment) {
    return build(reader, environment, null);
  }

  public SqlSessionFactory build(Reader reader, Properties properties) {
    return build(reader, null, properties);
  }

  public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    try {
      // 创建XMLConfigBuilder对象进行配置解析
      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        reader.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }
}
  • 创建XMLConfigBuilder对象并执行parse()来生成Configuration。
  • 通过build来创建DefaultSqlSessionFactory对象。


XMLConfigBuilder

public class XMLConfigBuilder extends BaseBuilder {

  public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

  private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    super(new Configuration());
    ErrorContext.instance().resource("SQL Mapper Configuration");
    this.configuration.setVariables(props);
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
  }

  public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    // 解析configuration的配置
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }


  private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      // 解析properties
      propertiesElement(root.evalNode("properties"));
      // 解析settings
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      // 解析Vfs
      loadCustomVfs(settings);
      // 解析typeAliases
      typeAliasesElement(root.evalNode("typeAliases"));
      // 解析plugins
      pluginElement(root.evalNode("plugins"));
      // 解析objectFactory
      objectFactoryElement(root.evalNode("objectFactory"));
      // 解析objectWrapperFactory
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      // 解析reflectorFactory
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      // 解析settings
      settingsElement(settings);
      // read it after objectFactory and objectWrapperFactory issue #631
      // 解析environments
      environmentsElement(root.evalNode("environments"));
      // 解析databaseIdProvider
      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);
    }
  }
}
  • XMLConfigBuilder的parseConfiguration负责解析Configuration配置文件。
  • 核心的parseConfiguration负责把解析的配置保存到Configuration对象当中。


参考文章

  • 源码参考
  • mybatis官网介绍
  • 深入理解mybatis原理
  • Mybatis3.4.x技术内幕
  • mybatis 3.x源码深度解析与最佳实践

你可能感兴趣的:(mybatis-3.4.6 顶层配置解析)