1.一次query流程
query真正执行的时候,才会去获取连接
{@link org.springframework.jdbc.core.JdbcTemplate#query}
{@link org.springframework.jdbc.core.JdbcTemplate#execute}
{@link org.springframework.jdbc.datasource.DataSourceUtils#getConnection}
{@link org.springframework.jdbc.datasource.DataSourceUtils#doGetConnection}
{@link org.apache.commons.dbcp2.BasicDataSource#getConnection}
{@link org.apache.commons.dbcp2.BasicDataSource#createDataSource}
{@link org.apache.commons.dbcp2.PoolingDataSource#getConnection}
<p/>
{@link org.springframework.jdbc.core.StatementCallback#doInStatement}
{@link org.apache.commons.dbcp2.DelegatingStatement#executeQuery}
2.核心方法createDataSource
protected DataSource createDataSource()
throws SQLException {
...
synchronized (this) {
...
PoolableConnectionFactory poolableConnectionFactory;
try {
poolableConnectionFactory = <span style="color:#ff0000;"><strong>createPoolableConnectionFactory</strong></span>(
driverConnectionFactory);
...
} catch (SQLException se) {
throw se;
}
...
if (success) {
// create a pool for our connections
<span style="color:#ff0000;"><strong>createConnectionPool</strong></span>(poolableConnectionFactory);
}
...
try {
dataSource = <span style="color:#ff0000;"><strong>createDataSourceInstance</strong></span>();
...
} catch (SQLException se) {
...
}
...
<span style="color:#ff0000;">startPoolMaintenance</span>();
return dataSource;
}
}
用createPoolableConnectionFactory方法构造一个PoolableConnectionFactory,然后createConnectionPool方法用该PoolableConnectionFactory构造饼初始化connectionPool变量。
createDataSourceInstance方法用上面构造好的connectionPool构造PoolingDataSource作为dataSource变量。
connectionPool(GenericObjectPool<PoolableConnection>,构造方法new GenericObjectPool<>)
dataSource(PoolingDataSource<PoolableConnection>,构造方法new PoolingDataSource<>(connectionPool))。
最后startPoolMaintenance开启Evictor任务,如果timeBetweenEvictionRunsMillis有设置的话。
可以把PoolingDataSource看作GenericObjectPool的包装,BasicDataSource的getConnection最终还是从GenericObjectPool中拿对象。
/**
* Create (if necessary) and return a connection to the database.
*
* @throws SQLException if a database access error occurs
* @return a database connection
*/
@Override
public Connection getConnection() throws SQLException {
if (Utils.IS_SECURITY_ENABLED) {
PrivilegedExceptionAction<Connection> action = new PaGetConnection();
try {
return AccessController.doPrivileged(action);
} catch (PrivilegedActionException e) {
Throwable cause = e.getCause();
if (cause instanceof SQLException) {
throw (SQLException) cause;
}
throw new SQLException(e);
}
}
return createDataSource().getConnection();
}
这里的createDataSource返回的就是PoolingDataSource,它的getConnection方法如下:
/**
* Return a {@link java.sql.Connection} from my pool,
* according to the contract specified by {@link ObjectPool#borrowObject}.
*/
@Override
public Connection getConnection() throws SQLException {
try {
C conn = _pool.borrowObject();
if (conn == null) {
return null;
}
return new PoolGuardConnectionWrapper<>(conn);
} catch(SQLException e) {
...
}
}
也是从_pool这个变量中调用borrowObject拿对象,这个_pool对象就是上面说的GenericObjectPool,所以最终还是调用GenericObjectPool的borrowObject方法拿对象。