标签:variable mes package bst apache https integer break 变量
本文,我们来分享 MyBatis 的解析器模块,对应 parsing
包。如下图所示:
在 《精尽 MyBatis 源码解析 —— 项目结构一览》 中,简单介绍了这个模块如下:
解析器模块,主要提供了两个功能:
- 一个功能,是对 XPath 进行封装,为 MyBatis 初始化时解析
mybatis-config.xml
配置文件以及映射配置文件提供支持。- 另一个功能,是为处理动态 SQL 语句中的占位符提供支持。
下面,我们就来看看具体的源码。因为 parsing
是基础支持层,所以建议胖友在我们讲解到的类和方法中,打折断点一起来了解。
org.apache.ibatis.parsing.XPathParser
,基于 Java XPath 解析器,用于解析 MyBatis mybatis-config.xml
和 **Mapper.xml
等 XML 配置文件。属性如下:
// XPathParser.java
|
document
属性,XML 被解析后,生成的 org.w3c.dom.Document
对象。
validation
属性,是否校验 XML 。一般情况下,值为 true
。entityResolver
属性,org.xml.sax.EntityResolver
对象,XML 实体解析器。默认情况下,对 XML 进行校验时,会基于 XML 文档开始位置指定的 DTD 文件或 XSD 文件。例如说,解析 mybatis-config.xml
配置文件时,会加载 http://mybatis.org/dtd/mybatis-3-config.dtd
这个 DTD 文件。但是,如果每个应用启动都从网络加载该 DTD 文件,势必在弱网络下体验非常下,甚至说应用部署在无网络的环境下,还会导致下载不下来,那么就会出现 XML 校验失败的情况。所以,在实际场景下,MyBatis 自定义了 EntityResolver 的实现,达到使用本地 DTD 文件,从而避免下载网络 DTD 文件的效果。详细解析,见 「3. XMLMapperEntityResolver」 。
xpath
属性,javax.xml.xpath.XPath
对象,用于查询 XML 中的节点和元素。如果对 XPath 的使用不了解的胖友,请先跳转 《Java XPath 解析器 - 解析 XML 文档》 中,进行简单学习,灰常简单。variables
属性,变量 Properties 对象,用来替换需要动态配置的属性值。例如:
<dataSource type="POOLED">
|
variables
的来源,即可以在常用的 Java Properties 文件中配置,也可以使用 MyBatis <property />
标签中配置。例如:
<properties resource="org/mybatis/example/config.properties">
|
username
和 password
属性,就可以替换上面的 ${username}
和 ${password}
这两个动态属性。PropertyParser#parse(String string, Properties variables)
方法。XPathParser 的构造方法有 16 个之多,当然基本都非常相似,我们来挑选其中一个。代码如下:
// XPathParser.java
|
调用 #commonConstructor(boolean validation, Properties variables, EntityResolver entityResolver)
方法,公用的构造方法逻辑。代码如下:
// XPathParser.java
|
调用 #createDocument(InputSource inputSource)
方法,将 XML 文件解析成 Document 对象。代码如下:
// XPathParser.java
|
XPathParser 提供了一系列的 #eval*
方法,用于获得 Boolean、Short、Integer、Long、Float、Double、String、Node 类型的元素或节点的“值”。当然,虽然方法很多,但是都是基于 #evaluate(String expression, Object root, QName returnType)
方法,代码如下:
// XPathParser.java
|
xpath
的 evaluate(String expression, Object root, QName returnType)
方法,获得指定元素或节点的值。eval 元素的方法,用于获得 Boolean、Short、Integer、Long、Float、Double、String 类型的元素的值。我们以 #evalString(Object root, String expression)
方法为例子,代码如下:
// XPathParser.java
|
<1>
处,调用 #evaluate(String expression, Object root, QName returnType)
方法,获得值。其中,returnType
方法传入的是 XPathConstants.STRING
,表示返回的值是 String 类型。<2>
处,调用 PropertyParser#parse(String string, Properties variables)
方法,基于 variables
替换动态值,如果 result
为动态值。这就是 MyBatis 如何替换掉 XML 中的动态值实现的方式。关于 PropertyParser ,我们会在 「5. PropertyParser」 详细解析。eval 元素的方法,用于获得 Node 类型的节点的值。代码如下:
// XPathParser.java
|
<1>
处,返回结果有 Node 对象和数组两种情况,根据方法参数 expression
需要获取的节点不同。<2>
处, 最终结果会将 Node 封装成 org.apache.ibatis.parsing.XNode
对象,主要为了动态值的替换。例如:
// XNode.java
|
org.apache.ibatis.builder.xml.XMLMapperEntityResolver
,实现 EntityResolver 接口,MyBatis 自定义 EntityResolver 实现类,用于加载本地的 mybatis-3-config.dtd
和 mybatis-3-mapper.dtd
这两个 DTD 文件。代码如下:
// XMLMapperEntityResolver.java
|
org.apache.ibatis.parsing.GenericTokenParser
,通用的 Token 解析器。代码如下:
// GenericTokenParser.java
|
#parse(String text)
方法,循环( 因为可能不只一个 ),解析以 openToken
开始,以 closeToken
结束的 Token ,并提交给 handler
进行处理,即 <x>
处。handler
这个 TokenHandler ,详细见 「5. TokenHandler」 。当然,这也是为什么 GenericTokenParser 叫做通用的原因,而 TokenHandler 处理特定的逻辑。org.apache.ibatis.parsing.PropertyParser
,动态属性解析器。代码如下:
// PropertyParser.java
|
<1>
,构造方法,修饰符为 private
,禁止构造 PropertyParser 对象,因为它是一个静态方法的工具类。<2>
,基于 variables
变量,替换 string
字符串中的动态属性,并返回结果。
<2.1>
,创建 VariableTokenHandler 对象。<2.2>
,创建 GenericTokenParser 对象。
openToken = {
,closeToken = }
,这不就是上面看到的 ${username}
和 {password}
的么。handler
类型为 VariableTokenHandler ,也就是说,通过它实现自定义的处理逻辑。关于它,在 「6.1 VariableTokenHandler」 中详细解析。<2.3>
,调用 GenericTokenParser#parse(String text)
方法,执行解析。org.apache.ibatis.parsing.TokenHandler
,Token 处理器接口。代码如下:
// TokenHandler.java
|
#handleToken(String content)
方法,处理 Token ,在 「4. GenericTokenParser」 中,我们已经看到它的调用了。TokenHandler 有四个子类实现,如下图所示:
parsing
包中,和解析器模块相关。VariableTokenHandler ,是 PropertyParser 的内部静态类,变量 Token 处理器。具体什么用途?上面不是已经整的明明白白啦,就不重复解释啦。
// PropertyParser.java
|
variables
属性,变量 Properties 对象。enableDefaultValue
属性,是否开启默认值功能。默认为 ENABLE_DEFAULT_VALUE
,即不开启。想要开启,可以配置如下:
<properties resource="org/mybatis/example/config.properties">
|
defaultValueSeparator
属性,默认值的分隔符。默认为 KEY_DEFAULT_VALUE_SEPARATOR
,即 ":"
。想要修改,可以配置如下:
<properties resource="org/mybatis/example/config.properties">
|
?:
。
// VariableTokenHandler 类里
|
标签:variable mes package bst apache https integer break 变量
原文地址:https://www.cnblogs.com/siye1989/p/11619340.html