code: private PoolEntry createPoolEntry()
     {
        try {
           final PoolEntry poolEntry = newPoolEntry();
  
           final long maxLifetime = config.getMaxLifetime();
           if (maxLifetime > 0) {
              // variance up to 2.5% of the maxlifetime
              final long variance = maxLifetime > 10_000 ? ThreadLocalRandom.current().nextLong( maxLifetime / 40 ) : 0;
              final long lifetime = maxLifetime - variance;
              poolEntry.setFutureEol(houseKeepingExecutorService.schedule(
                 () -> {
                    if (softEvictConnection(poolEntry, "(connection has passed maxLifetime)", false /* not owner */)) {
                       addBagItem(connectionBag.getWaitingThreadCount());
                    }
                 },
                 lifetime, MILLISECONDS));
           }
  
           return poolEntry;
        }
        catch (ConnectionSetupException e) {
           if (poolState == POOL_NORMAL) { // we check POOL_NORMAL to avoid a flood of messages if shutdown() is running concurrently
              logger.error("{} - Error thrown while acquiring connection from data source", poolName, e.getCause());
              lastConnectionFailure.set(e);
           }
           return null;
        }
        catch (SQLException e) {
           if (poolState == POOL_NORMAL) { // we check POOL_NORMAL to avoid a flood of messages if shutdown() is running concurrently
              logger.debug("{} - Cannot acquire connection from data source", poolName, e);
              lastConnectionFailure.set(new ConnectionSetupException(e));
           }
           return null;
        }
        catch (Exception e) {
           if (poolState == POOL_NORMAL) { // we check POOL_NORMAL to avoid a flood of messages if shutdown() is running concurrently
              logger.error("{} - Error thrown while acquiring connection from data source", poolName, e);
              lastConnectionFailure.set(new ConnectionSetupException(e));
           }
           return null;
        }
     }
docs: Creating new poolEntry.  If maxLifetime is configured, create a future End-of-life task with 2.5% variance from
  the maxLifetime time to ensure there is no massive die-off of Connections in the pool.