mybatis源码分析

XMLConfigBuilder的创建过程

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        inputStream.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }
public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
    this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
  }

在创建XMLConfigBuilder中,发现先创建了XPathParser类,这个类是什么呢?

// 代表要解析的整个XML文档
  private final Document document;
  // 是否开启验证
  private boolean validation;
  // EntityResolver,通过它可以声明寻找DTD文件的方法,例如通过本地寻找,而不是只能通过网络下载dtd文件
  private EntityResolver entityResolver;
  // MyBatis配置文件中的properties信息
  private Properties variables;
  // javax.xml.xpath.XPath工具
  private XPath xpath;

这个类主要是mybatis对XML文件进行解析的一个类,Document是mybatis配置文件转化而成的,xpath是java自带的xml解析器,相比Document而言,xpath更方便快捷,语法更简单,是一个轻量级的xml解析器。EntityResolver类主要是进行加载DTD文件的类,如果网络中不顺畅,则采用本地DTD加载。

因为其参数包括Xpath类,因此它是一个增强的Xpath类,里面封装了一些适用于mybatis的解析xml方法。

public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {
    commonConstructor(validation, variables, entityResolver);
    this.document = createDocument(new InputSource(inputStream));
  }

创建XPathParser中使用两个方法,分别是commonConstructor和createDocument。

commonConstructor方法是为XPatherParse设置了一些默认值

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();
  }

这段代码最重要的是将xpath创建出来,XPaherParse的解析xml主要靠xpath。

createDocument方法:创建Document对象

private Document createDocument(InputSource inputSource) {
    // important: this must only be called AFTER common constructor
    try {
      // DOM文档创建器的工厂
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      factory.setValidating(validation);

      factory.setNamespaceAware(false);
      factory.setIgnoringComments(true);
      factory.setIgnoringElementContentWhitespace(false);
      factory.setCoalescing(false);
      factory.setExpandEntityReferences(true);

      // DOM文档创建器
      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 {
        }
      });
      return builder.parse(inputSource);
    } catch (Exception e) {
      throw new BuilderException("Error creating document instance.  Cause: " + e, e);
    }
  }

好的,现在XPathParse现在创建出来,回到

public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
   this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
 }

我们先看看XMLConfigBuilder的参数

// 存储是否已经对config文件完成解析
 private boolean parsed;
 // 解析器
 private final XPathParser parser;
 // 要读取哪一个Environment节点,这里存储节点名
 private String environment;
 // 反射工厂
 private final ReflectorFactory localReflectorFactory = new DefaultReflectorFactory();
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
   super(new Configuration());
   ErrorContext.instance().resource("SQL Mapper Configuration");
   this.configuration.setVariables(props);
   this.parsed = false;
   this.environment = environment;
   this.parser = parser;
 }

其中,最初要的代码是构造方法的第一行super(new Configuration());这段代码将mybatis中许多注册中心都填充好默认值了,我们下面几章节再将。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值