今天我们来根据上一篇Mybatis(1)的案例我们来追追下源码:
我们从mybatis主要构件的执行流程:
那么我们先来看看SqlSessionFactoryBuilder创建SqlSessionFacctory的过程:
这边我们SqlSessionFactoryBuilder这个类:
public class SqlSessionFactoryBuilder {
public SqlSessionFactoryBuilder() {
}
//Reader读取mybatis配置文件
public SqlSessionFactory build(Reader reader) {
return this.build((Reader)reader, (String)null, (Properties)null);
}
//Reader读取mybatis配置文件
//Environment决定加载哪种环境(开发环境/生产环境)
public SqlSessionFactory build(Reader reader, String environment) {
return this.build((Reader)reader, environment, (Properties)null);
}
//mybatis配置文件 + properties, mybatis配置文件中能使用${}形式
public SqlSessionFactory build(Reader reader, Properties properties) {
return this.build((Reader)reader, (String)null, properties);
}
//通过XMLConfigBuilder解析mybatis配置,然后创建SqlSessionFactory对象
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
SqlSessionFactory var5;
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException var13) {
;
}
}
return var5;
}
//以下4个方法都只是Reader换成了InputStream
public SqlSessionFactory build(InputStream inputStream) {
return this.build((InputStream)inputStream, (String)null, (Properties)null);
}
public SqlSessionFactory build(InputStream inputStream, String environment) {
return this.build((InputStream)inputStream, environment, (Properties)null);
}
public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return this.build((InputStream)inputStream, (String)null, properties);
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
SqlSessionFactory var5;
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException var13) {
;
}
}
return var5;
}
//最后一个build方法使用了一个Configuration作为参数,并返回DefaultSqlSessionFactory
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}
从SqlSessionFactoryBuilder的代码我们可以总结出创建SqlSessionFactory的方式实际上是有两种:
1、不使用XML构建SqlSessionFactory :
实际上就是我们上一个篇张中使用的案例。就是使用Java程序而不是XML文件中直接创建配置实例,然后通过高 public SqlSessionFactory build(Configuration config) ;去创建SqlSessionFactory实例;
2、从XML中构建SqlSessionFactory :
实际上就是我们平常开发中常用的通过XML文件中构建SqlSessionFactory的实例;
不使用XML构建SqlSessionFactory,比较简单,我们这里主要看看从XML中构建SqlSessionFactory 的过程:
//通过XMLConfigBuilder解析mybatis配置,然后创建SqlSessionFactory对象
//参数reader:根据XML文档获取的Reader实例。
//参数environment:决定加载哪种环境(开发环境/生产环境)
//参数properties:那些properties(属性配置文件),那些属性可以用${propName}语法在配置文件中使用
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
SqlSessionFactory var5;
try {
//委托XMLConfigBuilder来解析xml文件
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
//构建SqlSessionFactory
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException var13) {
;
}
}
return var5;
}
接着我们来看看:
new XMLConfigBuilder(reader, environment, properties):
public XMLConfigBuilder(Reader reader, String environment, Properties props) {
this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props);
}
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
super(new Configuration());
ErrorContext.instance().resource("SQL Mapper Configuration");
this.configuration.setVariables(props);
this.parsed = false;
this.environment = environment;
this.parser = parser;
}
从代码我们可以看出来XMLConfigBuilder构健过程初始化的组件有:
Reader:通过xml配置文件获取的实例Reader
Properties:properties的配置信息对应的实例Properties
Evironment:环境对象
XMLMapperEntityResolver:DTDs校验xml配置语法的对象
XPathParser:xml的解析器。
接着我们来看看:SqlSessionthis.build(parser.parse()) :
先看下中:parser.parse():
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
//从根节点configuration
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
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);
}
}
从上面的代码我们就能看出,在mybatis的配置文件中:configuration节点之下,可以配置的信息分别为:
Properties全局参数
TypeAliases别名
Plugin插件
ObjectFactory对象
objectWrapperFactory
Settings设置
Environment环境
DatabaseidProvider 数据库标识
TypeHandler类型处理器
Mapper映射器
最后通过build(Configuration config)构建SqlSessionFactory:
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
总结下:
SqlSessionFactory构建过程(SqlSessionFactoryBuilder):
第一步:通过XMLConfigBuilder解析XML文件,读取配置信息,并保存到Configuration类中。备注:Mybatis几乎所有的配置都是保存在Configuration
第二部:使用Confinguration对象去创建SqlSessionFactory。备注:SqlSessionFactory是一个接口。
构建Configuration构建过程:
第一步:读取配置文件,包括基础配置的XML文件和映射器的XML文件
第二步:初始化基础配置比如Mybatis的别名等,一些重要的类对象,(插件,映射器,ObjectFatory,typeHandler对象等)
第三步:提供单例,为后续创建SessionFactory服务并提供配置参数
第四步:执行一些重要的对象方法,初始化配置信息。
初始化:
Properties全局参数
Settings设置
TypeAliases别名
TypeHandler类型处理器
ObjectFactory对象
Plugin插件
Environment环境
DatabaseidProvider 数据库标识
Mapper映射器