Mybatis源碼分析——2.一切的開始SqlSessionFactory

SqlSessionFactory開始創建

根據上一節我們知道,使用Mybatis時,操作過程如下:

  1. 根據配置文件使用SqlSessionFactoryBuilder創建SqlSessionFactory
  2. 使用SqlSessionFactory獲取一個SqlSession
  3. 通過SqlSession獲取XXXMapper對象
  4. 最後通過獲取到的XXXMapper對象調用我們在配置文件中聲明的方法。

根據Mybatis的例子中,我們可以按照如下代碼創建一個SqlSessionFactory:

// 指定配置文件位置
String resource = "org/mybatis/example/mybatis-config.xml";
// 獲取配置文件文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 通過SqlSessionFactoryBuilder使用配置文件創建一個`SqlSessionFactory`
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

經過了這一步 SqlSessionFactory就創建完成了,那麼我們可以先考察一下創建完成的SqlSessionFactory到底是什麼樣子的?事實上SqlSessionFactory是一個接口,在Mybatis中有兩個具體實現,分別是SqlSessionManagerDefaultSqlSessionFactory

在這裏插入圖片描述

這裏筆者先劇透一下,現在我們主要考察DefaultSqlSessionFactory類,先不管SqlSessionManager

考察DefaultSqlSessionFactory可以看到該類只有一個屬性:

private final Configuration configuration;

屬性名爲configuration(配置),這就是我們在配置文件中寫的配置,全部都存儲在這一個對象中。所以SqlSessionFactoryBuilder就解析了一個配置?

實際上是的,SqlSessionFactoryBuilder就解析了一個配置,它將配置文件中所有的配置都存儲到了Configuration對象中。

其實這種操作並不罕見,拿離我們最近的Java來說,我想正在讀這篇文章的你一定使用過Java,我們寫的代碼都是.java文件,這些文件會編譯成字節碼文件,這些字節碼文件都會加載到內存中,最後成爲一個個Class對象。Spring 中的Bean配置的xml文件也是同理。所以這是一個基本操作。每種配置文件都有一種解析方式,正是如此,使得配置文件與配置對象通過配置解析器解耦。

如下圖:

在這裏插入圖片描述

每個配置解析器都只做一件事,就是將配置文件解析成存儲配置的Configuration對象,這也符合了單一職責原則。這也算是一個工廠模式的實現吧,將具體的配置實現與配置對象解耦。不過這個工廠模式不限於只在代碼處實現,因爲配置文件也是它的一部分。

所以,Mybatis、Spring等一系列框架既有Xml文件配置、也有Java配置,甚至有的有yaml文件配置,都是因爲這個原因。

那麼接下來讓我們查看SqlSessionFactoryBuilder解析配置文件的邏輯,即SqlSessionFactoryBuilderbuild(InputStream)方法:

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

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      // 創建XML文件配置解析器
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      // 解析XML文件,並根據解析結果創建DefaultSqlSessionFactory
      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.
      }
    }
}
public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
}

可以看到所有的xml文件配置解析都封裝在了XMLConfigBuilder中。

通過上述的分析我們知道了,SqlSessionFactoryBuilder僅僅通過XMLConfigBuilder解析了XML文件的配置,並存儲在Configuration對象中 ,最後通過Configuration對象創建一個DefaultSqlSessionFactory

總結

通過分析SqlSessionFactoryBuilder,個人覺得這個類設計的並不是很好,因爲它將解析方式和 FactoryBuilder耦合了起來,使用SqlSessionFactoryBuilder就只能使用xml文件來配置Mybatis。如果想擴展其他方式就只能自己重寫一個FactoryBuilder

下一節:Mybatis源碼分析-3.開始配置解析

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