Mybatis 源碼學習:SqlSessionFactory 的創建過程

最近工作不忙,上班時間看了下 mybatis 源碼,學習學習…
我們要使用 mybatis,就必須得有 SqlSession 對象,它是 mybatis 的核心接口,它提供了執行 sql 、獲取 mapper 和管理事物的功能。而想要得到 SqlSession 對象。從源碼可知 SqlSession 是一個接口,並不能直接 new 出來,那麼肯定就有實現類讓我們使用,而 mybatis 確實也提供了對它的一個默認實現 DefaultSqlSession,它的源碼如下:

public class DefaultSqlSession implements SqlSession {
  private Configuration configuration;
  // Sql 執行器
  private Executor executor;
  private boolean autoCommit;
  private boolean dirty;

  public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
    this.configuration = configuration;
    this.executor = executor;
    this.dirty = false;
    this.autoCommit = autoCommit;
  }

  public DefaultSqlSession(Configuration configuration, Executor executor) {
    this(configuration, executor, false);
  }
  // 其它是對 sql 操作方法,不列舉
 }

從上述源碼可以知道,如果直接通過 new 的方式創建 SqlSession 對象,就需要自己構造 Configuration 和 Executor 對象,而以硬編碼方式創建 Configuration 對象比較麻煩。因此 mybatis 提供了通過 SqlSessionFactory 工程來獲取 SqlSession 對象,所以下面主要分析下 SqlSessionFactory 對象的創建過程。
SqlSessionFactory 工廠對象提供了幾個重載的 build() 方法來創建 SqlSessionFactory 對象,我們就拿這其中的一個進行分析。
創建 SqlSessionFactory
如上圖所示,其中核心代碼已圈紅,XMLConfigBuilder 對象是準備好解析 xml 配置文件的工具,真正解析 xml 配置文件的是 XMLConfigBuilder 的 parser() 方法。
解析 xml 文件
parse() 方法會首先判斷 xml 文件是否已被解析,感覺這個方法非線程安全的,如果多線程調用這個方法,可能都會執行 parserConfiguration() 方法。接下來就是通過 parseConfiguration() 方法解析 xml 文件中的各個元素,從如下源碼中可以看出,每個元素對應一個解析方法,所有解析的內容之後都會作爲 Configuration 對象的成員變量,其中最重要的元素解析方法是 mapperElement() 方法。

 private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      loadCustomVfs(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);
    }
  }

對 xml 配置文件解析完之後,返回 Configuration 對象,此對象包含了所有 mybatis 運行的配置信息,然後生成 DefaultSqlSessionFactory 對象。

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

至此,創建 SqlSessionFactory 對象的過程就完了,整個流程還是比較簡單清晰明瞭的。最後附上整個流程的時序圖:
sql

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章