每个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对象.