入口-BasicDataSource
/**
* Create (if necessary) and return a connection to the database.
*
* @throws SQLException if a database access error occurs
* @return a database connection
*/
public Connection getConnection() throws SQLException {
return createDataSource().getConnection();
}
获取连接的核心类
核心步骤
1.从连接池获取连接对象
2.校验连接是否有效
源码
GenericObjectPool
public T borrowObject() throws Exception {
long starttime = System.currentTimeMillis();
GenericObjectPool.Latch<T> latch = new GenericObjectPool.Latch();
byte whenExhaustedAction;
long maxWait;
//排队处理
synchronized(this) {
whenExhaustedAction = this._whenExhaustedAction;
maxWait = this._maxWait;
this._allocationQueue.add(latch);
}
//从连接池获取连接
this.allocate();
while(true) {
synchronized(this) {
this.assertOpen();
}
if (latch.getPair() == null && !latch.mayCreate()) {
switch(whenExhaustedAction) {
case 0:
synchronized(this) {
if (latch.getPair() == null && !latch.mayCreate()) {
this._allocationQueue.remove(latch);
throw new NoSuchElementException("Pool exhausted");
}
break;
}
case 1:
try {
synchronized(latch) {
if (latch.getPair() != null || latch.mayCreate()) {
break;
}
if (maxWait <= 0L) {
latch.wait();
} else {
long elapsed = System.currentTimeMillis() - starttime;
long waitTime = maxWait - elapsed;
if (waitTime > 0L) {
latch.wait(waitTime);
}
}
}
if (this.isClosed()) {
throw new IllegalStateException("Pool closed");
}
} catch (InterruptedException var51) {
boolean doAllocate = false;
synchronized(this) {
if (latch.getPair() == null && !latch.mayCreate()) {
this._allocationQueue.remove(latch);
} else if (latch.getPair() == null && latch.mayCreate()) {
--this._numInternalProcessing;
doAllocate = true;
} else {
--this._numInternalProcessing;
++this._numActive;
this.returnObject(latch.getPair().getValue());
}
}
if (doAllocate) {
this.allocate();
}
Thread.currentThread().interrupt();
throw var51;
}
if (maxWait <= 0L || System.currentTimeMillis() - starttime < maxWait) {
continue;
}
synchronized(this) {
if (latch.getPair() != null || latch.mayCreate()) {
break;
}
this._allocationQueue.remove(latch);
}
throw new NoSuchElementException("Timeout waiting for idle object");
case 2:
synchronized(this) {
if (latch.getPair() == null && !latch.mayCreate()) {
this._allocationQueue.remove(latch);
++this._numInternalProcessing;
}
break;
}
default:
throw new IllegalArgumentException("WhenExhaustedAction property " + whenExhaustedAction + " not recognized.");
}
}
boolean newlyCreated = false;
if (null == latch.getPair()) {
boolean var36 = false;
try {
var36 = true;
T obj = this._factory.makeObject();
latch.setPair(new ObjectTimestampPair(obj));
newlyCreated = true;
var36 = false;
} finally {
if (var36) {
if (!newlyCreated) {
synchronized(this) {
--this._numInternalProcessing;
}
this.allocate();
}
}
}
if (!newlyCreated) {
synchronized(this) {
--this._numInternalProcessing;
}
this.allocate();
}
}
//校验连接是否有效
try {
this._factory.activateObject(latch.getPair().value); //
if (this._testOnBorrow && !this._factory.validateObject(latch.getPair().value)) { //校验连接是否有效
throw new Exception("ValidateObject failed");
}
synchronized(this) {
--this._numInternalProcessing;
++this._numActive;
}
//返回连接对象
return latch.getPair().value; //返回连接对象
} catch (Throwable var47) {
PoolUtils.checkRethrow(var47);
try {
this._factory.destroyObject(latch.getPair().value);
} catch (Throwable var42) {
PoolUtils.checkRethrow(var42);
}
synchronized(this) {
--this._numInternalProcessing;
if (!newlyCreated) {
latch.reset();
this._allocationQueue.add(0, latch);
}
}
this.allocate();
if (newlyCreated) {
throw new NoSuchElementException("Could not create a validated object, cause: " + var47.getMessage());
}
}
}
}
从连接池获取连接对象
真正获取连接对象的是这个方法
private CursorableLinkedList<ObjectTimestampPair<T>> _pool; //连接池,是一个LinkedList
//从连接池获取连接
private synchronized void allocate() {
if (!this.isClosed()) {
GenericObjectPool.Latch latch; //封装了连接对象
while(!this._pool.isEmpty() && !this._allocationQueue.isEmpty()) {
latch = (GenericObjectPool.Latch)this._allocationQueue.removeFirst(); //从排队里获取一个进行处理
latch.setPair((ObjectTimestampPair)this._pool.removeFirst()); //从连接池获取连接对象
++this._numInternalProcessing;
synchronized(latch) {
latch.notify();
}
}
while(!this._allocationQueue.isEmpty() && (this._maxActive < 0 || this._numActive + this._numInternalProcessing < this._maxActive)) {
latch = (GenericObjectPool.Latch)this._allocationQueue.removeFirst();
latch.setMayCreate(true);
++this._numInternalProcessing;
synchronized(latch) {
latch.notify();
}
}
}
}
校验连接是否有效
public boolean validateObject(Object obj) {
if (obj instanceof Connection) {
try {
this.validateConnection((Connection)obj); //校验连接是否有效
return true; //如果连接有效,就返回true
} catch (Exception var3) {
return false; //如果连接无效,就返回false
}
} else {
return false;
}
}
public void validateConnection(Connection conn) throws SQLException {
String query = this._validationQuery;
if (conn.isClosed()) { //连接已经关闭
throw new SQLException("validateConnection: connection closed");
} else { //连接没有关闭,就校验连接是否有效:通过查询数据库,来校验连接是否有效
if (null != query) {
Statement stmt = null;
ResultSet rset = null;
try {
stmt = conn.createStatement();
if (this._validationQueryTimeout > 0) {
stmt.setQueryTimeout(this._validationQueryTimeout);
}
rset = stmt.executeQuery(query);
if (!rset.next()) {
throw new SQLException("validationQuery didn't return a row");
}
} finally {
if (rset != null) {
try {
rset.close();
} catch (Exception var14) {
}
}
if (stmt != null) {
try {
stmt.close();
} catch (Exception var13) {
}
}
}
}
}
}
数据结构
连接对象
封装了连接对象
private static final class Latch<T> {
private ObjectTimestampPair<T> _pair;
static class ObjectTimestampPair<T> implements Comparable<T> {
/** @deprecated */
@Deprecated
T value; //连接对象
/** @deprecated */
@Deprecated
long tstamp;
连接池
private CursorableLinkedList<ObjectTimestampPair<T>> _pool; //是一个集合,元素是连接对象
性能
获取连接的时候,有锁
private synchronized void allocate() { //同步方法
if (!this.isClosed()) {
GenericObjectPool.Latch latch;
while(!this._pool.isEmpty() && !this._allocationQueue.isEmpty()) {
latch = (GenericObjectPool.Latch)this._allocationQueue.removeFirst();
latch.setPair((ObjectTimestampPair)this._pool.removeFirst());
++this._numInternalProcessing;
synchronized(latch) {
latch.notify();
}
}
while(!this._allocationQueue.isEmpty() && (this._maxActive < 0 || this._numActive + this._numInternalProcessing < this._maxActive)) {
latch = (GenericObjectPool.Latch)this._allocationQueue.removeFirst();
latch.setMayCreate(true);
++this._numInternalProcessing;
synchronized(latch) {
latch.notify();
}
}
}
}
截图
1、获取连接对象
真正获取连接对象的方法
2、校验连接是否有效
dbcp和pool
dbcp是基于pool,底层的连接池都是pool实现的。