在 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
有哪些实现类,每一个实现类的功能是什么,没有达到接口与实现的分离。