mybatis源码解析3---XMLConfigBuilder解析
1.XMLConfigBuilder
XMLConfigBuilder类位于Mybatis包的org.apache.ibatis.builder.xml目录下,继承于BaseBuilder类,关于BaseBuilder类后续再看。
XMLConfigBuilder看名字能猜到是关于mybatis的XML配置的构造类,负责构造mybatis的XML配置的。
XMLConfigBuilder共有四个属性,代码如下:
1 private boolean parsed;//解析标识,因为Configuration是全局变量,只需要解析创建一次即可,true表示已经解析创建过,false则表示没有 2 private XPathParser parser; 3 private String environment;//环境参数 4 private ReflectorFactory localReflectorFactory = new DefaultReflectorFactory();
XMLConfigBuilder共有6个public构造方法和一个private的构造方法,如下:
1 public XMLConfigBuilder(Reader reader) { 2 this(reader, null, null); 3 } 4 5 public XMLConfigBuilder(Reader reader, String environment) { 6 this(reader, environment, null); 7 } 8 9 public XMLConfigBuilder(Reader reader, String environment, Properties props) { 10 this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props); 11 } 12 13 public XMLConfigBuilder(InputStream inputStream) { 14 this(inputStream, null, null); 15 } 16 17 public XMLConfigBuilder(InputStream inputStream, String environment) { 18 this(inputStream, environment, null); 19 } 20 21 public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) { 22 this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props); 23 } 24 25 private XMLConfigBuilder(XPathParser parser, String environment, Properties props) { 26 super(new Configuration());//调用父类的构造方法 27 ErrorContext.instance().resource("SQL Mapper Configuration"); 28 this.configuration.setVariables(props); 29 this.parsed = false; 30 this.environment = environment; 31 this.parser = parser; 32 }
很显然6个public的构造方法都是根据mybatis的配置文件流创建一个XPathParser对象,然后最终都调用了私有的构造方法,而私有的构造方法先是调用了父类BaseBuilder的构造方法,然后分别根据参数给四个属性赋值。
而上一篇文章提到了SqlSessionFactoryBuilder中是通过创建一个XMLConfigBuilder对象,然后调用了对象的parse()方法获取到一个Configuration对象。接下来就先看看XMLConfigBuilder的parse方法,如下:、
1 public Configuration parse() { 2 if (parsed) {//判断Configuration是否解析过,Configuration是全局变量,只需要解析创建一次即可 3 throw new BuilderException("Each XMLConfigBuilder can only be used once."); 4 } 5 parsed = true; 6 parseConfiguration(parser.evalNode("/configuration"));//调用下面的方法,parser.evalNode("/configuration")解析XML配置的configuration节点的内容,得到XNode对象 7 return configuration; 8 } 9 //根据root中存储的是configuration节点的内容 10 private void parseConfiguration(XNode root) { 11 try { 12 Properties settings = settingsAsPropertiess(root.evalNode("settings"));//设置settings配置 13 //issue #117 read properties first 14 propertiesElement(root.evalNode("properties"));//设置properties配置 15 loadCustomVfs(settings); 16 typeAliasesElement(root.evalNode("typeAliases"));//设置typeAliases配置 17 pluginElement(root.evalNode("plugins"));//设置plugins配置 18 objectFactoryElement(root.evalNode("objectFactory"));//设置objectFactory配置 19 objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));//设置objectWrapperFactory配置 20 reflectorFactoryElement(root.evalNode("reflectorFactory"));//设置reflectFactory配置 21 settingsElement(settings); 22 // read it after objectFactory and objectWrapperFactory issue #631 23 environmentsElement(root.evalNode("environments"));//设置environments配置 24 databaseIdProviderElement(root.evalNode("databaseIdProvider"));//设置databaseIdProvider配置 25 typeHandlerElement(root.evalNode("typeHandlers"));//设置typeHandlers配置 26 mapperElement(root.evalNode("mappers"));//设置mappers配置 27 } catch (Exception e) { 28 throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); 29 } 30 }
可以看出parse的作用是解析mybatis-config.xml的configuration节点的内容,然后挨个赋值给configuration对象的属性;
而XMLConfigBuilder的其他私有方法都是给根据XNode对象(XML配置的configuration节点内容)来给全局配置变量configuration的属性进行赋值,关于Configuration类的解析下一章会解析
总结:XMLConfigBuilder类的作用是根据全局配置文件mybatis-config.xml的流文件进行解析,解析xml中的各个节点,然后创建一个Configuration对象,并将xml中的节点属性赋值给Configuration对象