预览:Mybatis源码解析之解析器模块

主要功能

1、对XPath进行封装,为MyBatis初始化时解析mybatis-config.xml配置文件以及映射配置文件提供支持
2、处理动态SQL语句中的占位符提供支持
 

目标模块

预览:Mybatis源码解析之解析器模块_第1张图片
 

源码地址

https://gitee.com/bitongchong/mybatis-3/tree/feature/learningBranch/src/main/java/org/apache/ibatis/parsing
 

XPathParser

1、源码地址:

https://gitee.com/bitongchong/mybatis-3/blob/feature/learningBranch/src/main/java/org/apache/ibatis/parsing/XPathParser.java

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、源码地址:

https://gitee.com/bitongchong/mybatis-3/blob/feature/learningBranch/src/main/java/org/apache/ibatis/builder/xml/XMLMapperEntityResolver.java

2、代码功能:

实现EntityResolver接口,加载本地mybatis-3-config.dtd 和 mybatis-3-mapper.dtd 这两个 DTD 文件
 

GenericTokenParser

1、源码地址:

https://gitee.com/bitongchong/mybatis-3/blob/feature/learningBranch/src/main/java/org/apache/ibatis/parsing/GenericTokenParser.java

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、源码地址:

https://gitee.com/bitongchong/mybatis-3/blob/feature/learningBranch/src/main/java/org/apache/ibatis/parsing/PropertyParser.java

2、代码功能:

动态属性解析器
 
 

你可能感兴趣的:(MyBatis源码解析)