public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
    // 初始化,即主流程2
    init();

    if (filters.size() > 0) {
        // 责任链,内部也是触发下面的 getConnectionDirect 方法,只是要走一遍责任链上每个 filter 的逻辑,这里不做描述,后续放到流程 1.1 里体现
        FilterChainImpl filterChain = new FilterChainImpl(this);
        return filterChain.dataSource_connect(this, maxWaitMillis);
    } else {
        // 触发 getConnectionDirect
        return getConnectionDirect(maxWaitMillis);
    }
}

public DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException {
    int notFullTimeoutRetryCnt = 0;
    // 死循环
    for (;;) {
        /**
         * 真正返回出去的连接对象,注意这里是被 druid 包装成了 DruidPooledConnection 类型,
         * 实际上池子里存放的连接类型是 DruidConnectionHolder,DruidPooledConnection 类本身持有一个 holder 属性,
         * 用于保存真正的连接对象,而 DruidConnectionHolder 才是真正保存驱动连接对象的类。
         */
        // handle notFullTimeoutRetry
        DruidPooledConnection poolableConnection;
        try {
            // 从池子里获取连接,这一个后续放到流程 1.2 体现
            poolableConnection = getConnectionInternal(maxWaitMillis);
        } catch (GetConnectionTimeoutException ex) {
            // 出现了超时异常,在连接池没满且重试次数未超过上限的情况下,重试一次( notFullTimeoutRetryCount 默认是 0,所以至少可以重试一次)。
            if (notFullTimeoutRetryCnt <= this.notFullTimeoutRetryCount && !isFull()) {
                // 重试次数+1
                notFullTimeoutRetryCnt++;
                if (LOG.isWarnEnabled()) {
                    LOG.warn("get connection timeout retry : " + notFullTimeoutRetryCnt);
                }
                continue;
            }
            // 超过重试次数或者池子已满仍然获取失败,则直接抛出异常
            throw ex;
        }
        // testOnBorrow 开启时,每次都进行检测连接可用性
        if (testOnBorrow) {
            boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
            if (!validate) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("skip not validate connection.");
                }
                // 若连接不可用,则触发 discard,这个方法具体放到流程 1.4 体现
                discardConnection(poolableConnection.holder);
                continue;
            }
        } else {
            if (poolableConnection.conn.isClosed()) {
                // 传入null,避免重复关闭
                discardConnection(poolableConnection.holder); 
                continue;
            }

            // 不启用 testOnBorrow 的情况下,才会判断是否启用 testWhileIdle
            if (testWhileIdle) {
                final DruidConnectionHolder holder = poolableConnection.holder;
                long currentTimeMillis             = System.currentTimeMillis();
                long lastActiveTimeMillis          = holder.lastActiveTimeMillis;
                // 上次被使用的时间
                long lastExecTimeMillis            = holder.lastExecTimeMillis;
                // keepAlive 启用情况下,上次存活检测的时间,和 keepAliveBetweenTimeMillis 相关
                long lastKeepTimeMillis            = holder.lastKeepTimeMillis;

                if (checkExecuteTime
                        && lastExecTimeMillis != lastActiveTimeMillis) {
                    lastActiveTimeMillis = lastExecTimeMillis;
                }

                // 若在 timeBetweenEvictionRunsMillis 时间内,已经被 keepAliveBetweenTimeMillis 所检测,则不再次检测,避免重复检测耗费性能
                if (lastKeepTimeMillis > lastActiveTimeMillis) {
                    lastActiveTimeMillis = lastKeepTimeMillis;
                }

                // 计算出闲置时间
                long idleMillis                    = currentTimeMillis - lastActiveTimeMillis;

                long timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis;

                if (timeBetweenEvictionRunsMillis <= 0) {
                    timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
                }

                // 当闲置时间超出 timeBetweenEvictionRunsMillis(默认60s)时,则触发检查逻辑
                if (idleMillis >= timeBetweenEvictionRunsMillis
                        || idleMillis < 0 // unexcepted branch
                        ) {
                    boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
                    if (!validate) {
                        if (LOG.isDebugEnabled()) {
                            LOG.debug("skip not validate connection.");
                        }

                        //连接不可用,同样触发 discard
                        discardConnection(poolableConnection.holder);
                         continue;
                    }
                }
            }
        }

        // 若开启 removeAbandoned,则把当前拿到的连接放到 activeConnections 里,方便后续检查(后面流程 4.2 体现)
        if (removeAbandoned) {
            StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
            poolableConnection.connectStackTrace = stackTrace;
            // 设置连接获取时间为当前时间
            poolableConnection.setConnectedTimeNano();
            // 这个设置为 true,则在归还该连接时会在 activeConnections 里清除掉该连接对象
            poolableConnection.traceEnable = true;

            activeConnectionLock.lock();
            try {
                activeConnections.put(poolableConnection, PRESENT);
            } finally {
                activeConnectionLock.unlock();
            }
        }

        // 默认是不开事务的,所以这里是 true,不会触发下面的逻辑;这个不建议手动设置默认值,一般开启事务的工作自己做或者交给第三方框架(如 spring)做比较好
        if (!this.defaultAutoCommit) {
            poolableConnection.setAutoCommit(false);
        }

        // 最终返回可用连接
        return poolableConnection;
    }
}