接上次分享了日志组件后,我们这次来分享一个比较重要mybatis基础组件---数据源组件。提到数据源组件,我想问一个问题:请问从mybatis连接池获取一个数据库连接的过程是怎样的?你知道吗?这好像是BAT大厂的一道面试题吧。别着急我们慢慢来聊。
整体设计架构
今天来分享一下数据源组件的源码实现细节
工厂模式的设计思路
DataSourceFactory: 工厂模式的核心接口,调用者直接和工厂接口交互,用于获取具体的工厂实现类;
DataSource: java数据源的核心接口,用于抽象数据源行为;
UnpooledDataSourceFactory: 非池化工厂的具体实现类,用于创建非池化的数据源对象;
UnpooledDataSource: 主要用于构建原生的Connection对象;
PooledDataSourceFactory: 池化工厂的具体实现类,其继承UnpooledDataSourceFactory非池化工厂类的行为;主要职责创建池化的数据源对象;
PooledDataSource: 池化的数据源,它依赖UnpooledDataSource非池化数据源中连接等信息创建同步、线程安全的池化的数据源。
PooledConnection: 使用动态代理封装和增强原生的Connection数据库连接对象;
PoolState: 用于管理PooledConnection状态的组件,通过维护两个list分别管理空闲和活动的连接资源;
带着如下问题解读mybatis数据源组件设计实现源码
数据源组件为什么采用工厂模式实现 ?
池化数据源和非池化数据源有什么联系和区别,池化数据源需要考虑哪些问题?
数据源工厂源码实现
非池化数据源源码实现
池化数据源源码实现
从组件以上的设计思路和源码实现上,我们不难得出以下认知:
1. mybatis自身除了实现内置的数据源外,还要对三方数据源(如:durid, dbcp, c3p0等)的接入提供支持。这种业务设计需求下必须对数据源创建和管理,单独提供入口,并且能方便的切换和适配。
2. 采用常规创建对象的方式, 包括:直接new具体数据源类创建对象和通过反射机制创建对象等方式,很明显有以下缺陷:
缺陷一:对象的创建和使用的职责耦合在一起, 违反了单一职责原则;
缺陷二:当业务扩展时,必须要修改代码,违反了开闭原则;
那么我认为至少基于以上两大原则,mybatis才会考虑使用工厂模式。那工厂模式的明显优点有哪些呢?
1. 把对象的创建和使用的过程分开,这样就达到了把两者的职责分离的目的;
2. 如果创建对象过程比较复杂,创建过程统一放到工厂维护,即减少了重复代码,又方便了以后对相关过程代码的修改;
3. 当业务扩展时,只需要增加工厂子类,符合开闭原则;
OK, 这个问题解决了。那接下来我们将重点分析连接池化技术的设计实现源码。
池化数据源构建
封装池化、增强的数据库连接
封装对池化连接进行管理的核心数据结构
idleConnections:空闲池化连接集合, 当连接使用完关闭时,会把它放进这个空闲连接集合缓存; 当获取连接成功时,会将它从该集合中移除。
activeConnections: 正在使用的连接集合,当连接获取成功时,会把池化连接对象放入此集合;当连接关闭时,会把它从该集合中移除。
这两个list集合最终贯穿连接生命周期的始终。
池化数据源管理
拿连接的核心设计思路
拿连接方式和流程总结
上面正好也回答了文章一开始提出的问题!!
close连接的设计思路
关闭连接方式总结
总结
mybatis数据源组件其实设计很精妙,这种设计思路大家值得多思考和在我们的项目中借鉴,尤其是池化技术、设计模式!后面还为分享mybatis一些优秀的组件和设计思想,请继续关注!
来源:oschina
链接:https://my.oschina.net/u/4364921/blog/4517328