mybatis源码分析之初始化处理
以初始化xml为例进行分析,SqlSessionFactoryBuilder在执行builder方法的时候,就完成所有的初始化工作,由于初始化阶段,依赖的类很多,还是用类图来描述,初始化配置文件主要的类图如下:
mybatis主要有两个配置文件sqlmapConfig.xml以及sqlmap.xml,关于如何用jdk的api去解析xml配置文件的不去分析了,参考XPathParser,解析这两个配置文件的主要类的关系:
XMLConfigBuilder
处理sqlmapConfig.xml,解析标签并构造Configuration对象,Configuration是mybatis最核心的一个类,全靠它来串联整个执行流程。在实例化XMLConfigBuilder的时候创建它,初始化Configuration时,里面完成了很多与标签相关的类,如对象关系映射的两个类:TypeAliasRegistry(基本类型等别名映射)、TypeHandlerRegistry(结果集映射处理),xml的解析器初始化时也会加载mybatis自定义的DTD文件,xml必须满足DTD的约束才可以,参考XMLMapperEntityResolver类。还记得有次同事用IntelliJ打包部署项目,mybatis配置文件中文注释出现乱码,导致加载的时候出错,当时也没有找到原因,其实只要配置文件符合mybatis-3-config.dtd、mybatis-3-mapper.dtd约束就行了。解析sqlmapConfig.xml部分源代码如下:
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
super(new Configuration());
log.debug("XMLConfigBuilder构造函数初始化核心对象Configuration");
ErrorContext.instance().resource("SQL Mapper Configuration");
this.configuration.setVariables(props);
this.parsed = false;
this.environment = environment;
this.parser = parser;
}
private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first
log.debug("config.xml:解析各个节点");
propertiesElement(root.evalNode("properties"));
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
settingsElement(root.evalNode("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);
}
}
XMLMapperBuilder
mapper.xml对应的解析类,解析标签并把解析后的映射对象如cache、parameterMap、resultMap等对象通过MapperBuilderAssistant添加到Configuration。resultMap标签解析比较麻烦,参考Nested Results分析
XMLStatementBuilder
mapper.xml中包含select|insert|update|delete标签的解析类,标签内的内容构造sql单独由XMLScriptBuilder解析,最终会生成一个MappedStatement,并添加到Configuration。
MapperBuilderAssistant
XMLMapperBuilder的一个辅助类,build开头的方法完成映射(TypeHandler处理),add开头的方法将解析之后的节点添加到Configuration。
XMLScriptBuilder
sql脚本解析类, 主要用于构造sql语句,动态或静态sql的初始化。参考动态SQL分析