读数据库连接池DBCP 源码

在阅读DBCP源码前得先阅读commons-pool的原源码。
下面是几个主要的类的关系图。

[img]http://dl2.iteye.com/upload/attachment/0096/3510/b21f29c3-5f7c-38d6-8335-1c6858c5a893.jpg[/img]
1、BasicDataSource是我们最常见的类,配置数据源的时候就是写的这个。
它里面有一个getConnection方法,每次调用时就是从连接池中获取Connection。
具体的实现方法是在PoolingDataSource.java中,源码中如下:

public Connection getConnection() throws SQLException {
try {
Connection conn = (Connection)(_pool.borrowObject());
if (conn != null) {
conn = new PoolGuardConnectionWrapper(conn);
}
return conn;
} catch(SQLException e) {
throw e;
} catch(NoSuchElementException e) {
throw new SQLNestedException("Cannot get a connection, pool error " + e.getMessage(), e);
} catch(RuntimeException e) {
throw e;
} catch(Exception e) {
throw new SQLNestedException("Cannot get a connection, general error", e);
}
}

里面的_pool.borrowObject();就是从池中获取对象。
2、接着看PoolableConnectionFactory.java 这个就是commons-pool需要我们实现的创建池化对象的工厂类。

public Object makeObject() throws Exception {
Connection conn = _connFactory.createConnection();
if (conn == null) {
throw new IllegalStateException("Connection factory returned null from createConnection");
}
initializeConnection(conn);
if(null != _stmtPoolFactory) {
KeyedObjectPool stmtpool = _stmtPoolFactory.createPool();
conn = new PoolingConnection(conn,stmtpool);
stmtpool.setFactory((PoolingConnection)conn);
}
return new PoolableConnection(conn,_pool,_config);
}

这段代码就是调用ConnectionFactory创建连接对象的方法,并且返回的是封装好的PoolableConnection类。
3、最后看PoolingConnection.java 中的close方法。

public synchronized void close() throws SQLException {
if (_closed) {
return;
}

boolean isUnderlyingConectionClosed;
try {
isUnderlyingConectionClosed = _conn.isClosed();
} catch (SQLException e) {
try {
_pool.invalidateObject(this);
} catch(IllegalStateException ise) {
passivate();
getInnermostDelegate().close();
} catch (Exception ie) {

}
throw (SQLException) new SQLException("Cannot close connection (isClosed check failed)").initCause(e);
}

if (!isUnderlyingConectionClosed) {

try {
_pool.returnObject(this);
} catch(IllegalStateException e) {
passivate();
getInnermostDelegate().close();
} catch(SQLException e) {
throw e;
} catch(RuntimeException e) {
throw e;
} catch(Exception e) {
throw (SQLException) new SQLException("Cannot close connection (return to pool failed)").initCause(e);
}
} else {

try {
_pool.invalidateObject(this); // XXX should be guarded to happen at most once
} catch(IllegalStateException e) {
// pool is closed, so close the connection
passivate();
getInnermostDelegate().close();
} catch (Exception ie) {
}
throw new SQLException("Already closed.");
}
}

最后这个close方法里面是把对象给return到pool中。

看到这里,在使用DBCP时还是得调用close方法一下,把连接还给pool。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值