docs: public void close() {
          lock.lock();
          try {
              if (this.closed) {
                  return;
              }
  
              if (!this.inited) {
                  return;
              }
  
              if (logStatsThread != null) {
                  logStatsThread.interrupt();
              }
  
              if (createConnectionThread != null) {
                  createConnectionThread.interrupt();
              }
  
              if (destroyConnectionThread != null) {
                  destroyConnectionThread.interrupt();
              }
  
              if (destroySchedulerFuture != null) {
                  destroySchedulerFuture.cancel(true);
              }
  
              for (int i = 0; i < poolingCount; ++i) {
                  try {
                      DruidConnectionHolder connHolder = connections[i];
  
                      for (PreparedStatementHolder stmtHolder : connHolder.getStatementPool().getMap().values()) {
                          connHolder.getStatementPool().closeRemovedStatement(stmtHolder);
                      }
                      connHolder.getStatementPool().getMap().clear();
  
                      Connection physicalConnection = connHolder.getConnection();
                      physicalConnection.close();
                      connections[i] = null;
                      destroyCount.incrementAndGet();
                  } catch (Exception ex) {
                      LOG.warn("close connection error", ex);
                  }
              }
              poolingCount = 0;
  
              // close elasticsearch client
              if (this.client != null) {
                  this.client.close();
              }
  
              unregisterMbean();
  
              enable = false;
              notEmpty.signalAll();
              notEmptySignalCount++;
  
              this.closed = true;
              this.closeTimeMillis = System.currentTimeMillis();
  
              for (Filter filter : filters) {
                  filter.destroy();
              }
          } finally {
              lock.unlock();
          }
  
          if (LOG.isInfoEnabled()) {
              LOG.info("{dataSource-" + this.getID() + "} closed");
          }
      }