1.概述
解析器模块,主要提供了两个功能:
一个功能,是对 XPath 进行封装,为 MyBatis 初始化时解析 mybatis-config.xml 配置文件以及映射配置文件提供支持。
另一个功能,是为处理动态 SQL 语句中的占位符提供支持。
源码对应 parsing 包。
2. XPathParser
org.apache.ibatis.parsing.XPathParser ,基于 Java XPath 解析器,用于解析 MyBatis mybatis-config.xml 和 **Mapper.xml 等 XML 配置文件。属性如下:
/**
XML Document 对象
*/
private final Document document;
/**
是否检验
*/
private boolean validation;
/**
XML 实体解析器
*/
private EntityResolver entityResolver;
/**
变量 Properties 对象
*/
private Properties variables;
/**
* Java XPath 对象
*/
private XPath xpath;
2.1 构造方法
// XPathParser.java
/**
* 构造 XPathParser 对象
*
* @param xml XML 文件地址
* @param validation 是否校验 XML
* @param variables 变量 Properties 对象
* @param entityResolver XML 实体解析器
*/
public XPathParser(String xml, boolean validation, Properties variables, EntityResolver entityResolver) {
commonConstructor(validation, variables, entityResolver);
this.document = createDocument(new InputSource(new StringReader(xml)));
}
调用 #commonConstructor(boolean validation, Properties variables, EntityResolver entityResolver) 方法,公用的构造方法逻辑。代码如下:
// XPathParser.java
private void commonConstructor(boolean validation, Properties variables, EntityResolver entityResolver) {
this.validation = validation;
this.entityResolver = entityResolver;
this.variables = variables;
// 创建 XPathFactory 对象
XPathFactory factory = XPathFactory.newInstance();
this.xpath = factory.newXPath();
}
调用 #createDocument(InputSource inputSource) 方法,将 XML 文件解析成 Document 对象。代码如下:
// XPathParser.java
/**
* 创建 Document 对象
*
* @param inputSource XML 的 InputSource 对象
* @return Document 对象
*/
private Document createDocument(InputSource inputSource) {
// important: this must only be called AFTER common constructor
try {
// 1> 创建 DocumentBuilderFactory 对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(validation); // 设置是否验证 XML
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 exc