乐趣区

关于java:Mybatis源码分析四构建sqlSessionFactory

4.1 构建 sqlSessionFactory 流程

加载完资源文件,下一步就是构建 sqlSessionFactory

      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSessionFactoryBuilder 类次要办法有上面两个:

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      // 第一步,构建 XMLConfigBuilder 对象
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse()/* 第二步,生成 Configuration 对象 */)// 第三步,生成 DefaultSqlSessionFactory;
    } catch (Exception e) {throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {ErrorContext.instance().reset();
      try {inputStream.close();
      } catch (IOException e) {// Intentionally ignore. Prefer previous error.}
    }
  }

  public SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);
  }

构建 sqlSessionFactory 次要分 3 步:
第一步:依据配置文件、环境变量和 properties 构建 XMLConfigBuilder 对象。
第二步:.XMLConfigBuilder 对象生成 Configuration 对象 (parser.parse() 办法)。
第三步:. 依据 Configuration 对象生成 DefaultSqlSessionFactory。

通过以上三步,文章结尾的 sqlSessionFactory 的值等于一个 DefaultSqlSessionFactory 对象,构建 sqlSessionFactory 实现。上面咱们对波及到类和办法具体介绍。

4.2 SqlSessionFactoryBuilder

SqlSessionFactoryBuilder 是一个构建 sqlSessionFactory 的工具类,提供了一些重载的办法,次要的办法就是下面介绍的两个。

4.3 BaseBuilder

XMLConfigBuilder 是 BaseBuilder 的泛滥子类之一,XMLConfigBuilder 表演的是具体建造者的角色,BaseBuilder 表演的是形象建造者的角色。BaseBuilder 中外围宇段的含意如下:

  //Configuration MyBatis 初始化过程的外围对象,MyBatis 中简直全副的配置信息会保留到 Configuration 对象中
  //Configuration 对象是在 MyBatis 初始化过程中创立且是全局惟一的,也有人称它是一个“All-In-One”配置对象 
  protected final Configuration configuration;
  // 在 mybatis-config xml 配置文件中能够应用标签定义别名,这些定义的别名都会记录在 TypeAliasRegistry 对象中
  protected final TypeAliasRegistry typeAliasRegistry;
  //mybatis-config.xml 配置文件中能够应用标签增加自定义 TypeHandler 实现数据库类型与 Java 类型的转换
  protected final TypeHandlerRegistry typeHandlerRegistry;

typeAliasRegistry 与 typeHandlerRegistry,都是从 configuratioin 中来,所以也是全局惟一的,从 BaseBuilder 的构造函数能够看出:

public BaseBuilder(Configuration configuration) {
    this.configuration = configuration;
    this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
    this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();}

4.4 XMLConfigBuilder

XMLConfigBuilder 次要负责解析 mybatis-config.xml 配置文件,生成 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;
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

能够看到在 XMLConfigBuilder 的构造方法中 new 了一个 Configuration 对象,在 parse()办法中通过 parseConfiguration()办法解析 xml 文件,并赋值到 configuration。其中 parser.evalNode(“/configuration”)的作用是把 /configuration 节点封装成 XNode 对象,作为 parseConfiguration()办法的参数。
parseConfiguration()办法源代码如下:

 private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      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"));
      settingsElement(settings);
      // read it after objectFactory and objectWrapperFactory issue #631
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {throw new BuilderException("Error parsing SQL Mapper Configuration. Cause:" + e, e);
    }
  }

能够看到这个办法是解析各个节点,并赋值到 configuration 对象。
下一节具体解说各个节点的解析赋值。

退出移动版