结论提前:druid连接池,是在DruidDataSource中getConnection中调用init中初始化的,服务器刚启动,不查询数据库的话,并不会初始化连接池。
背景:项目使用了两个数据源,一个oracle,一个mysql,但是这两个数据源一个是内网,一个是外网,测试环境=内网不能访问外网,外网不能访问内网。故,发现一个问题,在内网下,服务器启动不了,因为初始化druid连接池失败了。而在外网下,服务器却能启动。
那么问题来了,如果服务器一启动,就会初始化druid连接池的话,为什么在外网下却能启动成功呢?
查看druid源码。
可以看到,druid会在getConnection中初始化连接池。然后在init里打一个断点,发现,mysql数据源服务器一启动就会调用getConnection初始化连接池,而oracle数据源不会,所以,这就是为什么,外网下可以启动服务的问题。
那么,为什么mysql数据源为什么服务器一启动就会getConnection初始化连接池呢?查看debug线程栈,发现,有一个线程,服务器一启动,就会不断轮询查询数据库,所以,测试环境,如果把这个线程停掉,就ok了。
@Override
public DruidPooledConnection getConnection() throws SQLException {
return getConnection(maxWait);
}
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);
}
}
结论:druid连接池,是在DruidDataSource中getConnection中调用init中初始化的,服务器刚启动,不查询数据库的话,并不会初始化连接池。