MyBatis 源码分析 - 配置文件解析过程 (2)

到此,一个 MyBatis 的解析过程就出来了,每个配置的解析逻辑都封装在了相应的方法中。在下面分析过程中,我不打算按照方法调用的顺序进行分析,我会适当进行一定的调整。同时,MyBatis 中配置较多,对于一些不常用的配置,这里会略过。那下面我们开始进行分析吧。

2.2 解析 properties 配置

解析properties节点是由propertiesElement这个方法完成的,该方法的逻辑比较简单。在分析方法源码前,先来看一下 properties 节点的配置内容。如下:

<properties resource="jdbc.properties"> <property value="coolblog"/> <property value="world"/> </properties>

在上面的配置中,我为 properties 节点配置了一个 resource 属性,以及两个子节点。下面我们参照上面的配置,来分析一下 propertiesElement 的逻辑。相关分析如下。

// -☆- XMLConfigBuilder private void propertiesElement(XNode context) throws Exception { if (context != null) { // 解析 propertis 的子节点,并将这些节点内容转换为属性对象 Properties Properties defaults = context.getChildrenAsProperties(); // 获取 propertis 节点中的 resource 和 url 属性值 String resource = context.getStringAttribute("resource"); String url = context.getStringAttribute("url"); // 两者都不用空,则抛出异常 if (resource != null && url != null) { throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference. Please specify one or the other."); } if (resource != null) { // 从文件系统中加载并解析属性文件 defaults.putAll(Resources.getResourceAsProperties(resource)); } else if (url != null) { // 通过 url 加载并解析属性文件 defaults.putAll(Resources.getUrlAsProperties(url)); } Properties vars = configuration.getVariables(); if (vars != null) { defaults.putAll(vars); } parser.setVariables(defaults); // 将属性值设置到 configuration 中 configuration.setVariables(defaults); } } public Properties getChildrenAsProperties() { Properties properties = new Properties(); // 获取并遍历子节点 for (XNode child : getChildren()) { // 获取 property 节点的 name 和 value 属性 String name = child.getStringAttribute("name"); String value = child.getStringAttribute("value"); if (name != null && value != null) { // 设置属性到属性对象中 properties.setProperty(name, value); } } return properties; } // -☆- XNode public List<XNode> getChildren() { List<XNode> children = new ArrayList<XNode>(); // 获取子节点列表 NodeList nodeList = node.getChildNodes(); if (nodeList != null) { for (int i = 0, n = nodeList.getLength(); i < n; i++) { Node node = nodeList.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { // 将节点对象封装到 XNode 中,并将 XNode 对象放入 children 列表中 children.add(new XNode(xpathParser, node, variables)); } } } return children; }

上面是 properties 节点解析的主要过程,不是很复杂。主要包含三个步骤,一是解析 properties 节点的子节点,并将解析结果设置到 Properties 对象中。二是从文件系统或通过网络读取属性配置,这取决于 properties 节点的 resource 和 url 是否为空。第二步对应的代码比较简单,这里就不分析了。有兴趣的话,大家可以自己去看看。最后一步则是将解析出的属性对象设置到 XPathParser 和 Configuration 对象中。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzyxw.html