在 mybatis源碼分析-環境搭建 一文中,咱們的測試代碼以下:java
public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); try { DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class); List<Dept> deptList = deptMapper.getAllDept(); System.out.println(deptList); } finally { sqlSession.close(); } }
其中如何生成 InputStream
對象在 mybatis源碼分析-配置文件加載 已經講解。本次將探究 SqlSessionFactory
對象的生成,也就是下面這行代碼執行了什麼。sql
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
首先上面那行代碼,建立了一個 SqlSessionFactoryBuilder
對象,源碼以下:apache
public class SqlSessionFactoryBuilder { public SqlSessionFactoryBuilder() { } //省略其它代碼 }
其次 SqlSessionFactoryBuilder
對象調用 build
方法,該方法源碼以下:segmentfault
public SqlSessionFactory build(InputStream inputStream) { return this.build((InputStream)inputStream, (String)null, (Properties)null); }
這個方法看來有重載方法,咱們繼續看其重載方法:session
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. } } }
這個方法主要關注:mybatis
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
這個構造函數將咱們的配置文件轉換爲 XMLConfigBuilder
對象,這裏面的邏輯十分複雜,咱們暫且不深究。app
return build(parser.parse());
這裏有兩處注意的地方,parser.parse()
返回一個Configuration
對象,這個對象保羅萬千,暫時也不深究。此外build
方法的實現以下:ide
public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }
它返回了 DefaultSqlSessionFactory
對象,而且將 Configuration
對象賦值其屬性,有源碼爲證:函數
public class DefaultSqlSessionFactory implements SqlSessionFactory { private final Configuration configuration; public DefaultSqlSessionFactory(Configuration configuration) { this.configuration = configuration; } //省略其它代碼 }
因爲 DefaultSqlSessionFactory
實現了 SqlSessionFactory
接口,那麼源碼分析
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
就水到渠成了。
本節不想討論
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
和
return build(parser.parse());
這兩行代碼的實現,由於它們太複雜了。目前只須要理解:
XMLConfigBuilder
對象XMLConfigBuilder
對象的一個 parse
方法將 XMLConfigBuilder
對象轉換爲 Configuration
對象,而該對象是 DefaultSqlSessionFactory
必需要的屬性。只有經過這個屬性,才能實現 SqlSessionFactory
中定義的接口方法。若是咱們來實現上面的功能,通常人會怎麼處理呢?
package com.yefengyu.mybatis; public interface SqlSessionFactory { void test(); }
package com.yefengyu.mybatis; import org.apache.ibatis.builder.xml.XMLConfigBuilder; import org.apache.ibatis.session.Configuration; import java.io.InputStream; public class DefaultSqlSessionFactory implements SqlSessionFactory { private Configuration configuration = null; public DefaultSqlSessionFactory(InputStream inputStream) { XMLConfigBuilder parser = new XMLConfigBuilder(inputStream); this.configuration = parser.parse(); } @Override public void test() { //使用 configuration 完成相關功能 } }
package com.yefengyu.mybatis; import org.apache.ibatis.io.Resources; import java.io.IOException; import java.io.InputStream; public class Main { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new DefaultSqlSessionFactory(inputStream); sqlSessionFactory.test(); } }
這三段代碼想模擬mybatis建立SqlSessionFactory
對象的過程,好比SqlSessionFactory
有一些接口 test
,其實現類 DefaultSqlSessionFactory
實現此方法須要 Configuration
對象,須要從 InputStream
經過構造函數傳入並解析爲 Configuration
對象。測試代碼中直接使用 DefaultSqlSessionFactory
建立 SqlSessionFactory
對象。
這種方式的缺點:
SqlSessionFactory
實現的話,把 InputStream
轉換爲 Configuration
的過程在每一個構造函數都會有。SqlSessionFactory
有哪些實現類,每一個實現類的功能是什麼,沒有達到接口與實現的分離。