每个mybatis应用都是以一个SqlSessionFactory实例为核心的,而SqlSessionFactory的生成其实很简单,只需要一下三行代码(基于XML配置文件实现):

        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

首先需要有XML配置文件,然后转成InputStream,然后使用SqlSessionFactoryBuilder生成SqlSessionFactory对象。接下来看一下具体做了什么:

首先,调用的是一个build(InputStream inputStream)方法:

  public SqlSessionFactory build(InputStream inputStream) {
    return build(inputStream, null, null);
  }

可以看到这个方法直接调用了build(InputStream inputStream, String environment, Properties properties)方法,后面两个参数传的是null。看下具体实现:

 public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());
    } 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.
      }
    }
  }

忽略try...catch...,首先根据参数new了一个XMLConfigBuilder对象,可以看出这个XML解析器装载了一个实现了EntityResolver接口的XMLMapperEntityResolver对象。然后调用了下一个build(Configuration config)方法。看下parser.parse()

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

可以看出解析XML配置文件的代码是:parseConfiguration(parser.evalNode("/configuration"));

  private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      // 解析properties节点配置
      propertiesElement(root.evalNode("properties"));
      // 解析settings节点配置
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      // 根据settings配置,装载自定义Vfs
      loadCustomVfs(settings);
      // 根据settings配置,装载对应的日志实现
      loadCustomLogImpl(settings);
      // 解析别名配置
      typeAliasesElement(root.evalNode("typeAliases"));
      // 解析插件配置
      pluginElement(root.evalNode("plugins"));
      // 解析objectFactory配置
      objectFactoryElement(root.evalNode("objectFactory"));
      // 解析objectWrapperFactory配置
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      // 解析reflectorFactory配置
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      // 把settings中的属性设置到configuration对象中去
      settingsElement(settings);
      // 解析environment配置
      // read it after objectFactory and objectWrapperFactory issue #631
      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);
    }
  }

至此,mybatis配置文件解析完毕,调用build(Configuration config)方法生成SqlSessionFactory对象:

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

可以看出,返回的是DefaultSqlSessionFactory对象.


星河
7 声望1 粉丝

Easy choice, hard life; hard choice, easy life.