Mybatis框架学习之DataSource实例化过程
来源:互联网 发布:php注册登陆页面代码 编辑:程序博客网 时间:2024/06/06 02:21
主要介绍Mybatis启动过程中DataSource实例化的过程。
Mybatis中DataSource体系
MybatisDataSource整体简介
Mybatis中关于数据库的类都在org.apache.ibatis.datasource
包中
Mybatis配置文件中关于数据库的配置:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 重点关注
<dataSource type="POOLED">
的type属性、其有三种取值:- POOLED:使用Mybatis自带的数据库连接池来管理数据库连接
- UNPOOLED:不使用任何数据库连接池来管理数据库连接
- JNDI:jndi形式使用数据库连接、主要用于项目正常使用的时候
类与类之间的关系:
每一条线都是一种关系、简单解释一下
1. PooledDataSource实现java.sql.DataSource接口
2. PooledDataSource内部持有一个DataSource引用
3. UnpooledDataSource实现java.sql.DataSource接口
4. PooledDataSource内部持有一个UnpooledDataSource引用
5.PooledDataSourceFactory无参构造方法体中将其父类UnpooledDataSourceFactory持有的引用DataSource实例化为PooledDataSource
6. PooledDataSourceFactory继承UnpooledDataSourceFactory
7. UnpooledDataSourceFactory无参构造方法将其持有的引用DataSource实例化为UnpooledDataSource
8. UnpooledDataSourceFactory持有一个DataSource引用、用于返回实例化好的DataSource。
Mybatis中DataSource实例化整体过程
这里以使用Mybatis自带的数据库连接池为例。也就是type为 “POOLED”类型的数据连接。
- 根据配置文件中type的类型实例化具体的DataSourceFactory。这里是POOLED所以实例化的是PooledDataSourceFactory。
- 通过PooledDataSourceFactory来获取DataSource具体实例:PooledDataSource
对于第一步更详细点的过程:
- 在Mybatis初始化Configuration对象时、Configuration中属性TypeAliasRegistry同样被实例化、并且在Configuration的无参构造方法中对TypeAliasRegistry注册了许多常用的类(以键值对的形式保存在TypeAliasRegistry的属性
private final Map<String, Class<?>> TYPE_ALIASES = new HashMap<String, Class<?>>();
中、也包括TypeAliasRegistry无参构造方法注册的基本java类型。 - 通过配置文件中type指定的”POOLED”在TypeAliasRegistry中查找其对应的类:PooledDataSourceFactory
- 调用其newInstance()实例化
- PooledDataSourceFactory继承自UnpooledDataSourceFactory、所以UnpooledDataSourceFactory先被实例化、
- UnpooledDataSourceFactory无参构造方法中实例化了其DataSource引用为UnpooledDataSource。
- 接着实例化PooledDataSourceFactory、其无参构造方法体将父类UnpooledDataSourceFactory持有的DataSource实例化为PooledDataSource。
- PooledDataSource实例化时初始化了一些关于数据库连接池的配置信息
- PooledDataSource的无参构造方法中将其持有的UnpooledDataSource实例化。
- UnpooledDataSource中关于数据库连接的属性值在实例化DataSourceFactory之后读取properties值设置到对应属性上。
具体过程
从上一篇中知道Mybatis初始化过程是解析Mybatis配置文件并装配Configuration对象。从Mybatis基础使用中知道Mybatis数据库连接信息的配置是在environments标签中配置的:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
所以想要了解DataSource初始化过程可以从XMLConfigBuilder中的parse方法入手:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 这里同样有关于数据库事务的配置、具体事务有关的后面再说
主要看如何实例化DataSource、同样从上面代码中我们知道只是将DataSource实例化了而没有进行任何操作、原因是只有具体执行某SQL语句的时候才会使用DataSource来获取数据库连接。
获取DataSource关键代码:
- 1
- 2
- 根据配置文件中dataSource标签中内容实例化DataSourceFactory
- 通过DataSourceFactory获取DataSource
下面首先看如何根据dataSource标签内容实例化DataSourceFactory
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 上面一段代码关键点在于
resolveClass(type)
- 经过一系列的方法调用、最终返回结果的方法是:
TypeAliasRegistry
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 这里重点在于TypeAliasRegistry是何时实例化的
- 上一篇初始化过程中知道Configuration中有一个私有变量
protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
- 进一步看看Configuration实例化的时候其无参构造函数体就知道其缘由
- 上一篇初始化过程中知道Configuration中有一个私有变量
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 从上面可以看出TypeAliasRegistry在实例化之后并初始化了其内部私有变量
private final Map<String, Class<?>> TYPE_ALIASES = new HashMap<String, Class<?>>();
来保存一些Type alias(类型别名)供后面程序使用。
从上面代码typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
可以看出最后返回的是PooledDataSourceFactory
。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- PooledDataSourceFactory继承UnpooledDataSourceFactory
其中UnpooledDataSourceFactory拥有一个DataSource的protected级别的属性protected DataSource dataSource;
并且其构造函数:
- 1
- 2
- 3
- 4
对比PooledDataSourceFactory的构造函数:
- 1
- 2
- 3
知道最终UnpooledDataSourceFactory的protected DataSource dataSource;
实例是:PooledDataSource
。
到这里只要知道PooledDataSource是什么、那么返回的DataSource就是什么。
当然在这之前还需要一步、就是将配置文件中的数据库连接信息设置到最后生成的DataSourceFactory(在这里就是PooledDataSourceFactory)中去。这个过程中使用了一个Mybatis很长用的用于操作反射的封装类:MetaObject。提供了一些简便的获取、设置类等通过反射来操作类的方法、以后有时间专门看一眼。
下面的主要目标就是看PooledDataSource调用其无参构造方法时到底做了什么。
PooledDataSource是java.sql.DataSource的一个实现类、其属性与无参构造方法如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 设置了一些作为数据库连接池初始化使用的参数
- 无参方法体中实例话了属性
dataSource = new UnpooledDataSource();
- UnpooledDataSource无参构造函数是空方法题
- 要注意的是:前面实例化DataSourceFactory的时候最后一步是设置属性。其实就是通过MetaObject来将属性值设置到UnpooledDataSource的数据库连接属性上了。
到这里、关于数据库DataSource类的实例话也就结束了。
补充
对数据库实例化做个总结:
当使用数据库连接池时、即<dataSource type="POOLED">
时、DataSourceFactory具体实例是PooledDataSourceFactory。返回的DataSource具体实例是内部持有UnpooledDataSource实例的PooledDataSource。
当不使用数据库连接池时、即<dataSource type="UNPOOLED">
时、DataSourceFactory具体实例是UnpooledDataSourceFactory。返回的DataSource具体实例是UnpooledDataSource实例。
- Mybatis框架学习之DataSource实例化过程
- Mybatis深入之DataSource实例化过程
- mybatis源码学习之org.apache.ibatis.datasource.jndi包
- 框架基础学习之--mybatis
- mybatis学习之框架原理
- mybatis源代码分析之datasource包
- mybatis 源码系列 组件之 datasource
- mybatis 框架简单实例
- MyBatis学习之调用存储过程
- mybatis源码学习之数据源创建过程
- mybatis 源码学习之getMapper过程分析
- MyBatis框架学习之增删改查
- Mybatis框架之常用标签学习
- 框架学习之mybatis整合spring
- mybatis学习之路----框架搭建
- 模仿与学习MyBatis - 1.2 DataSource与Session
- Mybatis+servlet实例(Mybatis学习)
- Spring MVC +Mybatis + Maven 配置之dataSource配置
- 微信公众号基础01_利用git免费在新浪云搭建测试号服务器
- LeetCode笔记:183. Customers Who Never Order
- Linux内核-内存-硬件高速缓存和TLB原理
- 字符集和字符编码
- Windows核心编程笔记(二) Widnwos下的字符处理
- Mybatis框架学习之DataSource实例化过程
- Leetcode Swap Nodes in Pairs
- git pull和git pull --rebase的不同
- TCP的拥塞控制
- android的服务进程Service的创建及启动
- 网络程序设计课程项目学习总结-SA16225018-曾龙飞
- HTML+CSS学习笔记三
- Go语言中的多核调度
- xz命令--Linux命令应用大词典729个命令解读