主要功能
1、对XPath进行封装,为MyBatis初始化时解析mybatis-config.xml配置文件以及映射配置文件提供支持
2、处理动态SQL语句中的占位符提供支持
目标模块
源码地址
XPathParser
1、源码地址:
2、代码功能:
基于Java Xpath的解析器,用于解析mybatis-config.xml和xxMapper.xml等XML配置文件,便于获取配置文件中配置的属性值
3、具体实现:
3.1、类属性:
/**
* XML Document 对象
*/
private final Document document;
/**
* 是否进行校验
*/
private boolean validation;
/**
* XML实体解析器
*/
private EntityResolver entityResolver;
/**
* 变量properties对象
*/
private Properties variables;
/**
* Java XPath对象
*/
private XPath xpath;
3.2、构造方法(部分):
public XPathParser(String xml) {
// 首先调用通用构造方法,减少重复代码
commonConstructor(false, null, null);
this.document = createDocument(new InputSource(new StringReader(xml)));
}
public XPathParser(InputStream inputStream, boolean validation) {
commonConstructor(validation, null, null);
this.document = createDocument(new InputSource(inputStream));
}
... ...
3.3、初始化
private void commonConstructor(boolean validation, Properties variables, EntityResolver entityResolver) {
this.validation = validation;
this.entityResolver = entityResolver;
this.variables = variables;
XPathFactory factory = XPathFactory.newInstance();
this.xpath = factory.newXPath();
}
3.4、将各种类型的配置文件资源转化为Document对象,便于后面对这些配置文件进行数据解析:
private Document createDocument(InputSource inputSource) {
// important: this must only be called AFTER common constructor
// 重要:该方法必须在common constructor调用之后再来调用
try {
// 由InputSource(XML实体的单个输入源)来构建Document对象的流程:
// DocumentBuilderFactory --> DocumentBuilder --> Document
// 1.创建DocumentBuilderFactory对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
factory.setValidating(validation);
factory.setNamespaceAware(false);
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(false);
factory.setCoalescing(false);
factory.setExpandEntityReferences(true);
// 2.创建DocumentBuilder对象
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(entityResolver);
builder.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException exception) throws SAXException {
throw exception;
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
throw exception;
}
@Override
public void warning(SAXParseException exception) throws SAXException {
// NOP
}
});
// 3.解析XML文件,创建Document对象
return builder.parse(inputSource);
} catch (Exception e) {
throw new BuilderException("Error creating document instance. Cause: " + e, e);
}
}
3.5、eval 方法族
XPathParser 提供了一系列的 eval*() 方法,用于获得 Boolean、Short、Integer、Long、Float、Double、String、Node 类型的
元素或节点的“值”,基于evaluate()方法
/**
* 用于获得 Boolean、Short、Integer、Long、Float、Double、String、Node 类型的元素或节点的“值”
* @param expression 表达式
* @param root 指定节点
* @param returnType 返回类型
* @return 配置的值
*/
private Object evaluate(String expression, Object root, QName returnType) {
try {
return xpath.evaluate(expression, root, returnType);
} catch (Exception e) {
throw new BuilderException("Error evaluating XPath. Cause: " + e, e);
}
}
XMLMapperEntityResolver
1、源码地址:
2、代码功能:
实现EntityResolver接口,加载本地mybatis-3-config.dtd 和 mybatis-3-mapper.dtd 这两个 DTD 文件
GenericTokenParser
1、源码地址:
2、代码功能:
通用的Token解析器,比如 #{user} is admin ,这儿的user就是一个 token ,可以通过TokenHandler的handleToken()方法返回解析出的值,从而达到Token解析目的(这也是为什么 GenericTokenParser 叫做通用的原因——TokenHandler 接口的唯一方法handle()处理特定的逻辑)
3、具体实现:
3.1、类属性
/**
* 开始的 Token 字符串
*/
private final String openToken;
/**
* 结束的 Token 字符串
*/
private final String closeToken;
/**
* 处理expression(通过token生成)的handler
*/
private final TokenHandler handler;
3.2、parse
解析的具体实现流程
PropertyParser
1、源码地址:
2、代码功能:
动态属性解析器