可以这么说,MyBatis初始化的过程,就是创建Configuration对象的过程。

1 Configuration介绍

顾名思义,Configuration表示配置,该对象中维护了很多mybatis的配置参数。
大致可分为四部分:

  1. 环境变量(Environment)
  2. 配置参数
  3. 缓存集合
  4. 插件及其他

1.1 环境变量(Environment)

通过查看org.apache.ibatis.mapping.Environment的源码。
Environment仅维护了一个id,TransactionFactory以及DataSource。

  1. id environment的唯一标识,如dev,prod等
  2. TransactionFactory 事务工厂,负责事务管理,Mybatis提供了两套事务管理
    2.1 org.apache.ibatis.transaction.jdbc 基于JDBC实现事务管理
    2.2 org.apache.ibatis.transaction.managed 用于扩展第三方事务管理
    推荐帖【Transaction事务模块】
  3. DataSource 数据源
    推荐帖【JAVA数据源】

1.2 配置参数

Configuration提供了一些默认配置参数,并可通过get/set方法去修改参数值。
如mapUnderscoreToCamelCase,cacheEnabled等。

1.3 缓存集合

Configuration维护了很多缓存容器,如caches、resultMaps等,暂未深究

1.4 插件及其他

Configuration提供了InterceptorChain插件责任链,并对Mybatis的四大核心组件(Executor除外)进行拦截

  1. 执行器 Executor
  2. StatementHandler
  3. ParameterHandler
  4. ResultSetHandler
    推荐帖【MyBatis插件原理】 共有五篇,PageHelper就是基于插件实现的。

除了插件之外,其他还有一些mapperRegistry用于注册Mapper等,暂未深究

2 Configuration初始化

Mybatis提供了两种方式初始化Configuration

2.1 API构建

    // 构建数据源,此处使用了Mybatis的PooledDataSource, 通常采用第三方数据源,如Druid
    PooledDataSource dataSource= new PooledDataSource();
    dataSource.setDriver("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://xxxx:3306/test");
    dataSource.setUsername("username");
    dataSource.setPassword("password");

    
    // 构建环境 并将其标识为dev
    Environment dev = new Environment("dev", new JdbcTransactionFactory(), dataSource);
    
    // 构建Configuration
     Configuration config= new Configuration(dev);

2.2 XML构建

MyBatis提供XMLConfigBuilder通过XML构建Configuration。

而MyBatis解析XML主要通过以下三个类:
2.1 XMLMapperEntityResolver
    获取XML本地dtd,避免从网络获取
2.2 XPathParser
    解析XML为Document对象,可获取子节点
    封装细节:
        2.2.1 获取Document -> createDocument()
            DocumentBuilderFactory.newInstance().newDocumentBuilder().parse()
        2.2.2 获取子节点XNode及其他类型子节点 -> evalXX()..
            xpath.evaluate() //xpath由XPathParser初始化时创建 -> XPathFactory.newInstance().newXPath()
2.3 XNode
    XNode 对Node以及XPathParser进行了封装,可获取子节点及节点属性
        2.3.1 获取子节点 -> evalXX()
            在2.2.2中说明了XPathParser通过xpath.evaluate 获取Node节点,并返回XNode(实际是对Node以及XPathParser进行了封装)
            而XNode获取子节点实际还是通过XPathParser获取。
        2.3.2 获取节点属性 -> getXXAttribute()
            XNode初始化时,通过Node获取节点属性,并解析为Properties类型,提供属性获取。
MyBatis实际上通过XPathParser和XNode封装了通过DocumentBuilder解析XML为Document,以及通过XPath解析节点属性的过程。

XMLConfigbuilder则通过XPathParser和XNode获取XML的配置属性,
实现了Configuration的初始化(实现方法:XMlConfigBuilder.parseConfiguration)

贴一张 MyBatis3 的XML配置结构图

clipboard.png

资料来源:MyBatis3 XML配置

最后,在结尾总结一下Configuration初始化时涉及的设计模式
工厂模式:TransactionFactory
动态代理模式:InterceptorChain 此处名称采用了责任链,实际上是通过Plugin动态代理嵌套实现。


roylion
204 声望25 粉丝

读书破万卷


引用和评论

0 条评论