3)关闭数据源
dataSource.close();3 连接池 Druid 实现原理我们学习数据源的实现,可以从如下五个核心角度分析:
- 初始化
- 创建连接
- 回收连接
- 归还连接
- 销毁连接
主从是指显示的调用 init 方法,而被动是指获取连接时完成初始化 。

文章插图
图片
调用getConnection方法时,返回的对象是连接接口的封装类 DruidConnectionHolder 。在初始化方法内,数据源创建三个连接池数组 ,他们分别是:

文章插图
图片
- connections:用于存放能获取的连接对象 。
- evictConnections:用于存放需要丢弃的连接对象 。
- keepAliveConnections:用于存放需要保活的连接对象 。
数据源「预热」分为同步和异步两种方式 ,见下图:

文章插图
图片
从上图,我们可以看到同步创建连接时,是原生 JDBC 创建连接后,直接放入到 connections 数组对象里 。
异步创建线程需要初始化 createScheduler , 但默认并没有配置 。
数据源预热之后,启动了两个任务线程:创建连接线程和销毁连接线程 。

文章插图
图片
3.2 创建连接这一节,我们重点学习 Druid 数据源如何创建连接 。
CreateConnectionThread 本质是一个单线程在死循环中通过 condition 等待,被其他线程唤醒 ,并实现创建数据库连接逻辑 。

文章插图
图片
笔者将 run 方法做了适当简化,当满足了条件之后,才创建数据库连接 :
- 必须存在线程等待 , 才创建连接。
- 防止创建超过最大连接数 maxAcitve。

文章插图
图片
3.3 获取连接我们详细解析了创建连接的过程 , 接下来就是应用如何获取连接的过程 。
DruidDataSource#getConnection 方法会调用到 DruidDataSource#getConnectionDirect 方法来获取连接,实现如下所示 。

文章插图
图片
核心流程是
1)在 for 循环内,首先调用 getConnectionDirect内,调用getConnectionInternal 从池子里获取连接对象;
2)获取连接后,需要根据 testOnBorrow 、testWhileIdle 参数配置判断是否需要检测连接的有效性;
3)最后假如需要判断连接是否有泄露,则配置 removeAbandoned 来关闭长时间不适用的连接,该功能不建议再生产环境中使用 , 仅用于连接泄露检测诊断 。
接下来进入获取连接的重点:getConnectionInternal 方法如何从池子里获取连接 。

文章插图
图片
getConnectionInternal()方法中拿到连接的方式有三种:
- 直接创建连接(默认配置不会执行)需要配置定时线程池 createScheduler,当连接池已经没有可用连接,且当前借出的连接数未达到允许的最大连接数,且当前没有其它线程在创建连接 ;
推荐阅读
- 退房时酒店为什么不再查房了?前台工作人员说出真相,原来如此!
- 演员张潮:再婚娶小20岁娇妻,62岁又做父亲,大女儿也是知名演员
- 灵堂缺席的三天王,戳穿了娱圈的人情冷暖,刘德华的话,有人信了
- 演员李芸:与前夫离婚后,再婚嫁小提琴家,现在儿女双全
- 红毯再放异彩,美貌争议背后,业务能力能否成就顶流之巅
- 灵堂迟来的三天王,戳穿了娱圈的人情冷暖,刘德华的话,有人信了
- 没想到《一念关山》剧外能这么热闹!男主无差别抢所有人戏份翻车
- “渣男”原形毕露?也许再多的名和利,都救不了48岁的于震!
- 夏天长湿疹别再喝啤酒
- “刀郎停更”却被媒体称赞,这一次,韩红的话,终于有人信了!
