在 HikariPool 初始化的時候,已經知道負責鏈接建立的 addConnectionExecutor 這個線程池,那麼只要找到向它提交任務的地方就能夠了;ide
發現 HikariPool 實現了 IBagStateListener#addBagItem 接口,在裏邊執行了鏈接建立的動做spa
// 等待獲取db鏈接的線程數
public void addBagItem(final int waiting)
{
final boolean shouldAdd = waiting - addConnectionQueueReadOnlyView.size() >= 0; // Yes, >= is intentional.
if (shouldAdd) {
addConnectionExecutor.submit(poolEntryCreator);
}
else {
logger.debug("{} - Add connection elided, waiting {}, queue {}", poolName, waiting, addConnectionQueueReadOnlyView.size());
}
}
再看哪裏會調用 HikariPool#addBagItem, 找到 ConcurrentBag#borrow(timeout, timtUnit) 在從底層鏈接的容器申請db鏈接時,若是沒有可用的 poolEntry,則會 調用 HikariPool#addBagItem 去提交新建db鏈接的任務;線程
因此在鏈接申請 HikariPool#getConnection() → concurrentBag#borrow 失敗的話,也會觸發鏈接的建立debug
HikariPool#addBagItem 和 HouseKeeper 的邏輯不同,addBagItem的場景是此刻db鏈接就不夠用了,須要去建立接口