XMLConfigBuilder的创建
在上一篇SqlSessionFactory的创建的过程中创建了XMLConfigBuilder对象,使用了两种构造函数
public XMLConfigBuilder(Reader reader, String environment, Properties props) {
this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props);
}
public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
this(new XPathParser(inputStream, 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的创建都是通过这个构造函数的。而XMLConfigBuilder是继承抽象类BaseBuilder
因此在初始化XMLConfigBuilder的过程中,会先初始化BaseBuilder,而BaseBuilder只提供了一个构造方法
public BaseBuilder(Configuration configuration) {
this.configuration = configuration;
this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
}
此方法需要一个Configuration类型的参数,因此在创建XMLConfigBuilder的过程中,会先创建一个默认的Configuration
属性
- parsed属性用来防止多次多次读取配置文件具体的实现如下:
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
- parser//xml解析器
- environment环境
解析配置文件
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
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.
}
}
}
由上面的方法得知,解析主要调用XMLConfigBuilder的parse()方法
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
上面得知最后调用的方法为parseConfiguration
private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first
//解析properties元素
propertiesElement(root.evalNode("properties"));
//解析setting元素
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
//解析typeAliases元素
typeAliasesElement(root.evalNode("typeAliases"));
//解析plugins元素
pluginElement(root.evalNode("plugins"));
//解析objectFactory元素
objectFactoryElement(root.evalNode("objectFactory"));
//objectWrapperFactory
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);
}
}
解析的顺序
- configuration 配置
- properties 属性
- settings 设置
- typeAliases 类型命名
- typeHandlers 类型处理器
- objectFactory 对象工厂
- plugins 插件
- environments 环境
- environment 环境变量
- transactionManager 事务管理器
- dataSource 数据源
- mappers 映射器