背景
数据库连接池的概念大家应该都很熟悉,类似dbcp、c3p0,还有如今常用的druid等,使用时无非就是从网上抄几段配置,调一下参数,但是深入理解数据库连接池的原理在如今的Java开发中还是很有必要的,这里以dbcp为例,简要分析一下数据库连接池的实现原理
这里我采用的版本是2.5.0版本
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.5.0</version>
</dependency>
分析
准备
我们先来看一段原生jdbc代码(省略了异常捕获):
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/xxxxxx";
Connection conn = DriverManager.getConnection(url, "user", "password");
Statement stat = conn.createStatement();
ResultSet set = stat.executeQuery(sql);
while(set.next()) {
System.out.println(set.getString(2));
}
stat.close();
conn.close();
代码结构这里不关心,重点是其中的一句
Connection conn = DriverManager.getConnection(url, "user", "password");
为什么要单独拿这一条出来说呢?因为我们使用数据库连接池也是调用了getConnection方法,在JDBC 2.0 API中,Java提倡使用DateSource接口来获取连接
我们现在的重点就是找到dhcp提供的DataSource接口,如果我们使用过dhcp配置,就一定见过这样的配置
spring:
datasource:
type: org.apache.commons.dbcp2.BasicDataSource
我们就以BasicDataSource作为突破点,这个类实现了DataSource接口:
public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBeanRegistration, AutoCloseable
既然我们要探究原理,就不要关注细枝末节的部分,我们直接点进最核心的getConnection方法,同时为了代码结构清晰,这里忽略所有异常捕获语句:
@Override
public Connection getConnection() throws SQLException {
if (Utils.IS_SECURITY_ENABLED) {
final PrivilegedExceptionAction<Connection> action = new PaGetConnection();
return AccessController.doPrivileged(action);
}
return createDataSource(