1 DruidDataSource類圖
DruidDataSource為整個鏈接池的基礎(chǔ)入口革娄,實現(xiàn)了JDBC的Datasource
類圖.png
2 初始化-構(gòu)造函數(shù)
?public DruidDataSource(){
this(false);
}
public DruidDataSource(boolean fairLock){
super(fairLock);
configFromPropety(System.getProperties());
}
參數(shù)用來控制鎖的公平性盹沈,默認false非公平
configFromPropety 方法從配置中犁功,初始化各種配置屬性,屬性及其多睹簇,瀏覽一下即可
看一下super的構(gòu)造函數(shù)屁置,定義了鎖的狀態(tài)
?public DruidAbstractDataSource(boolean lockFair){
lock = new ReentrantLock(lockFair);
notEmpty = lock.newCondition();
empty = lock.newCondition();
}
然后調(diào)用init()方法初始化
init又非常得長搞监,主要做了如下幾件事情:
- 獲取鎖(可中斷) lock.lockInterruptibly();
- 生成dataSource的ID DruidDriver.createDataSourceId()
- 校驗配置參數(shù)的合法性
- 通過SPI加載Filter initFromSPIServiceLoader()
- 根據(jù)配置加載JDBC驅(qū)動 resolveDriver(); initCheck();
- 創(chuàng)建連接Holder的數(shù)組
connections = new DruidConnectionHolder[maxActive];
evictConnections = new DruidConnectionHolder[maxActive];
keepAliveConnections = new DruidConnectionHolder[maxActive];
- 根據(jù)設(shè)置,同步或者異步創(chuàng)建連接PhysicalConnectionInfo,放到之前的Holder數(shù)組connections 中
- 創(chuàng)建線程池径簿,日志罢屈,創(chuàng)建者和銷毀者
- 創(chuàng)建線程池有一個CountDownLatch,異步創(chuàng)建完成后篇亭,初始化就結(jié)束了
- 后續(xù)還有一些異常處理缠捌,日志等等
3 獲取連接
public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
init();
if (filters.size() > 0) {
FilterChainImpl filterChain = new FilterChainImpl(this);
return filterChain.dataSource_connect(this, maxWaitMillis);
} else {
return getConnectionDirect(maxWaitMillis);
}
}
主要鏈路
getConnectionDirect(maxWaitMillis)->
getConnectionInternal(maxWaitMillis)->
createPhysicalConnection()->
DruidConnectionHolder ->pollLast()
失敗重新創(chuàng)建一個->new DruidConnectionHolder(this, pyConnInfo);
最后返回通過Holder獲取的connection new DruidPooledConnection(holder);
其他
生成DataSourceId的時候,用了幾個原子類來記錄偏移量译蒂,后續(xù)看到再標注
long delta = (this.id - 1) * 100000;
this.connectionIdSeedUpdater.addAndGet(this, delta);
this.statementIdSeedUpdater.addAndGet(this, delta);
this.resultSetIdSeedUpdater.addAndGet(this, delta);
this.transactionIdSeedUpdater.addAndGet(this, delta);
看源碼的方法曼月,可以從Test單元測試類開始
DruidDataSourceTest 初始化到關(guān)閉的流程走了一遍