系列
开篇
- 这个系列是基于mybatis-3.4.6版本的源码解析,这篇文章主要分析mybatis的底层配置解析流程。
- SqlSessionFactory是通过SqlSessionFactoryBuilder工厂类创建的,而不是直接使用构造器
reader = Resources.getResourceAsReader(resouce);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
顶层配置解析流程
配置解析流程
- 配置解析的流程如上图,核心在于SqlSessionFactoryBuilder和XMLConfigBuilder。
- parseConfiguration负责解析configuration.xml生成Configuration对象。
SqlSessionFactoryBuilder
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(Reader reader) {
return build(reader, null, null);
}
public SqlSessionFactory build(Reader reader, String environment) {
return build(reader, environment, null);
}
public SqlSessionFactory build(Reader reader, Properties properties) {
return build(reader, null, properties);
}
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
// 创建XMLConfigBuilder对象进行配置解析
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}
- 创建XMLConfigBuilder对象并执行parse()来生成Configuration。
- 通过build来创建DefaultSqlSessionFactory对象。
XMLConfigBuilder
public class XMLConfigBuilder extends BaseBuilder {
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
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;
}
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
// 解析properties
propertiesElement(root.evalNode("properties"));
// 解析settings
Properties settings = settingsAsProperties(root.evalNode("settings"));
// 解析Vfs
loadCustomVfs(settings);
// 解析typeAliases
typeAliasesElement(root.evalNode("typeAliases"));
// 解析plugins
pluginElement(root.evalNode("plugins"));
// 解析objectFactory
objectFactoryElement(root.evalNode("objectFactory"));
// 解析objectWrapperFactory
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
// 解析reflectorFactory
reflectorFactoryElement(root.evalNode("reflectorFactory"));
// 解析settings
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
// 解析environments
environmentsElement(root.evalNode("environments"));
// 解析databaseIdProvider
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
// 解析typeHandlers
typeHandlerElement(root.evalNode("typeHandlers"));
// 解析mappers
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
}
- XMLConfigBuilder的parseConfiguration负责解析Configuration配置文件。
- 核心的parseConfiguration负责把解析的配置保存到Configuration对象当中。
参考文章
网友评论