DBCP数据库连接池原理分析
在比较大的项目中,需要不断的从数据库中获取数据,Java中则使用JDBC连接数据库,但是获取数据库的连接可是相当耗时的操作,每次连接数据库都获得 、销毁数据库连接,将是很大的一个开销。为了解决这种开销,则使用了对象池的技术。程序启动时,先创建一定数量的数据库连接对象,然后只要一用到就直接从对象池中取出连接对象,然后使用完成后不对其销毁,而是再返回到对象池中,这样使连接池对象能反复使用,虽然增加了启动时所需要的时间但是提高了响应速度,对象池也相当于是一个缓存。
这里有DBCP的一些配置参数,通过这些参数可以大致知道其原理是怎么样的?
初始化为0大小的对象池,当需要Connection对象时,此时 当前总共连接对象小于maxActivity,空闲连接数小于maxldle,则创建一个连接对象(使用池对象工厂),当Connection的数量达到最大活跃数的时候,则进行等待,直到有可用的连接或者到达maxWait抛出异常。
例如在tomcat中,利用JNDI来查找到资源javax.sql.DataSource的实现,如果使用dbcp连接池,则该实现为org.apache.commons.dbcp.BasicDataSource。我们可以从这个称为“数据源”的类中调用getConnection方法来获得与数据库的连接。但内部是如何实现的呢?对象池在其中占据什么位置呢?这一切对于外部使用者来说是透明的。
BasicDataSource的getConnection首先建立了PoolingDataSource对象来getConnection。这个PoolingDataSource对象中引用了ObjectPool,在getConnection()时,是从ObjectPool中借用了一个对象,既调用ObjectPool.borrowObject()方法。而对于熟悉commons-pool的程序员来说,ObjectPool肯定有与之对应的Factory创建对象,并放到池中。因此dbcp通过实现了接口org.apache.commons.pool.PoolableObjectFactory的类org.apache.commons.dbcp.PoolableConnectionFactory的makeObject方法来创建连接Connection对象。然而PoolableConnectionFactory持有对ConnectionFactory的引用,ConnectionFactory可以有3种策略来创建Connection对象。其中DriverConnectionFactory调用了数据库厂商提供的Driver来获得Connection。
数据库连接池的原理和线程池的原理很像,可以结合理解。
这里有一个细节使用完成之后,他是如何将对象放入对象池呢?通过调用Close方法,你也许会疑问,这不是进行对象的销毁吗?确实,但是原代码中使用了反射 的动态代理的技术,在运行时修改了close方法。
//获取连接的方法
private Connection getConnection()
{ try {
//获取一个连接
final Connection conn=DriverManager.getConnection(url, user, password); //把连接交给动态代理类转换为代理的连接对象
Connection myconn = (Connection)Proxy.newProxyInstance(
MyPool.class.getClassLoader(),
new Class[] {Connection.class},
//编写一个方法处理器
new InvocationHandler() { @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object value = null; //当遇到close方法,就会把对象放回连接池中,而不是关闭连接
if(method.getName().equals("close"))
{
MyPool.connList.addLast(conn);
}else
{
//其它方法不变
value = method.invoke(conn, args);
}
return value;
}}
);
return myconn;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
DBCP数据库连接池原理分析的更多相关文章
- DBCP连接池原理分析及配置用法
DBCP连接池介绍 ----------------------------- 目前 DBCP 有两个版本分别是 1.3 和 1.4. DBCP 1.3 版本需要运行于 JDK 1.4-1.5 ,支持 ...
- 【转】DBCP连接池原理分析
---------------------------- 目前 DBCP 有两个版本分别是 1.3 和 1.4. DBCP 1.3 版本需要运行于 JDK 1.4-1.5 ,支持 JDBC 3. DB ...
- DBCP连接池原理分析(转载)
DBCP连接池介绍 ----------------------------- 目前 DBCP 有两个版本分别是 1.3 和 1.4. DBCP 1.3 版本需要运行于 JDK 1.4-1.5 ,支持 ...
- 【Java EE 学习 16 上】【dbcp数据库连接池】【c3p0数据库连接池】
一.回顾之前使用的动态代理的方式实现的数据库连接池: 代码: package day16.utils; import java.io.IOException; import java.lang.ref ...
- JAVA和C#中数据库连接池原理与应用
JAVA和C#中数据库连接池原理 在现在的互联网发展中,高并发成为了主流,而最关键的部分就是对数据库操作和访问,在现在的互联网发展中,ORM框架曾出不穷, 比如:.Net-Core的EFCore.Sq ...
- SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
作为后台服务开发,在日常工作中我们天天都在跟数据库打交道,一直在进行各种CRUD操作,都会使用到数据库连接池.按照发展历程,业界知名的数据库连接池有以下几种:c3p0.DBCP.Tomcat JDBC ...
- Java数据库连接池原理与简易实现
1.什么是数据库连接池 我们现在在开发中一定都会用到数据库,为了提高我们的系统的访问速度,数据库优化是一个有效的途径.我们现在开发中使用数据库一般都要经历以下的四个步骤:(1)加载数据库的驱动类,(2 ...
- java并发包&线程池原理分析&锁的深度化
java并发包&线程池原理分析&锁的深度化 并发包 同步容器类 Vector与ArrayList区别 1.ArrayList是最常用的List实现类,内部是通过数组实现的, ...
- JDBC数据库连接池原理
JDBC是java数据库连接的简称.它是一种用于实行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口组成.其相关的API都在java.sql.*包下 ...
随机推荐
- Linux_Shell_ Map 的使用和遍历
定义初始化map declare -A map=([") 输出所有key echo ${map[@]} 输出key对应的值 "]} 遍历map for key in ${!map[ ...
- 服务器部署php项目
windows服务器 首先打开开始菜单,点击运行. 然后输入mstsc,确定 输入你的服务器IP,点击连接 这里选择 是 然后就到了登录界面,输入用户名和密码就可以了 linux服 ...
- loj #2023. 「AHOI / HNOI2017」抛硬币
#2023. 「AHOI / HNOI2017」抛硬币 题目描述 小 A 和小 B 是一对好朋友,他们经常一起愉快的玩耍.最近小 B 沉迷于**师手游,天天刷本,根本无心搞学习.但是已经入坑了几个 ...
- Vue.js 60分钟快速入门
原文链接:http://www.cnblogs.com/keepfool/p/5619070.html Vue.js介绍 Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和 ...
- shell脚本安装jdk
#!/bin/bash BASE_SERVER=192.168.1.11 yum install -y wget wget $BASE_SERVER/soft-all/jdk-7u45-linux-x ...
- Gson的fromJson()方法
Gson提供了fromJson()方法来实现从Json相关对象到Java实体的方法. 在日常应用中,我们一般都会碰到两种情况,转成单一实体对象和转换成对象列表或者其他结构. 先来看第一种: 比如jso ...
- spring boot 1.4.2.RELEASE+Thymeleaf+mybatis 集成通用maper,与分页插件:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot ...
- [转载]np.where()使用说明
转载自https://www.cnblogs.com/massquantity/p/8908859.html#4072620 numpy.where() 有两种用法: 1. np.where(cond ...
- ssh免密登录linux服务器
Ssh免密登录 sshd服务 sshd简介: SSH 密钥为登录 Linux 服务器提供了更好且安全的机制.运行 ssh-keygen 后,将会生成公私密钥对.你可以将公钥放置到任意服务器,从持有私钥 ...
- git 工作中常用命令
git 命令: git init : 初始化 git add . :添加所有文件 git status :查看状态 若果是第一次会提示你输入你的 邮箱 和姓名: git commit ...