ConnectionPool

  • 连接池
/**
 * 连接池
 */
public class ConnectionPool implements DataSource {

    // 连接配置

    /** 驱动类 */
    private String driver;
    /** 数据库地址 */
    private String url;
    /** 账号 */
    private String username;
    /** 密码 */
    private String password;

    // 连接池配置

    /** 最大活跃连接数 */
    private int maxActive;

    /** 最大空闲连接数*/
    private int maxIdle;

    /** 活跃连接 */
    private List<PooledConnection> activeConnections = new ArrayList<>();

    /** 空闲连接 */
    private List<PooledConnection> idleConnections = new ArrayList<>();

    private final Object lock = new Object();

    /** 所有JDBC驱动 */
    private static Map<String, Driver> driverMap = new ConcurrentHashMap<>();
    static {
        Enumeration<Driver> driverEnumeration = DriverManager.getDrivers();
        while (driverEnumeration.hasMoreElements()) {
            Driver driver = driverEnumeration.nextElement();
            driverMap.put(driver.getClass().getCanonicalName(), driver);
        }
    }

    public ConnectionPool(String driver, String url, String username, String password, int maxActive, int maxIdle) {
        this.driver = driver;
        this.url = url;
        this.username = username;
        this.password = password;
        this.maxActive = maxActive;
        this.maxIdle = maxIdle;
    }

    /**
     * 借出连接
     */
    private Connection borrowConnection(String username, String password) throws SQLException {
        PooledConnection connection = null;

        while (connection == null) {
            synchronized (lock) {
                if (idleConnections.size() > 0) {
                    // 有空闲连接
                    connection = idleConnections.remove(0);

                } else {
                    if (activeConnections.size() < maxActive) {
                        // 未达到最大活跃连接数,则生成一个新连接
                        Connection realConnection = doGetConnection(username, password);
                        connection = new PooledConnection(realConnection, this);

                    } else {
                        // 已达到最大数量,等待
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            break;
                        }
                    }
                }

                if (connection != null) {
                    // 借出时检查
                    if (connection.isValid()) {
                        activeConnections.add(connection);
                    } else {
                        connection.invalidate();
                        connection.getRealConnection().close();
                        connection = null;
                    }
                }
            }
        }

        if (connection == null) {
            throw new SQLException("The connection pool returned a null connection");
        }

        // 返回代理对象
        return connection.getProxyConnection();
    }

    /**
     * 生成一个真正的连接
     */
    private Connection doGetConnection(String username, String password) throws SQLException {
        initializerDriver();
        Connection connection = DriverManager.getConnection(url, username, password);
        // 配置连接
        return connection;
    }

    /**
     * 初始化数据库驱动
     */
    private synchronized void initializerDriver() throws SQLException {
        if (!driverMap.containsKey(driver)) {
            try {
                Class.forName(driver);
            } catch (ClassNotFoundException e) {
                throw new SQLException("Error setting driver " + driver + " : " + e);
            }
        }
    }

    /**
     * 归还连接
     */
    void returnConnection(PooledConnection connection) throws SQLException {
        synchronized (lock) {
            // 从活跃连接集合去掉
            activeConnections.remove(connection);
            // 归还时检查
            if (connection.isValid()) {
                if (idleConnections.size() < maxIdle) {
                    // 未达到最大空闲连接数,归还池中
                    idleConnections.add(connection);
                    // 通知等待连接的线程
                    lock.notifyAll();
                } else {
                    // 关闭连接
                    connection.invalidate();
                    connection.getRealConnection().close();
                }
            }
        }
    }

    /**
     * 检查连接
     */
    boolean pingConnection(Connection connection) {
        if (connection == null) {
            return false;
        }
        try {
            if (connection.isClosed()) {
                return false;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
        try {
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery("SELECT 1");
            resultSet.close();
            statement.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            try {
                connection.close();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            return false;
        }
    }

    /**
     * 关闭连接池
     */
    void closeAll() {
        Consumer<List<PooledConnection>> closePool = (pool) -> {
            if (pool != null) {
                Iterator<PooledConnection> iterator = pool.iterator();
                while (iterator.hasNext()) {
                    PooledConnection pooledConnection = iterator.next();
                    iterator.remove();

                    pooledConnection.invalidate();
                    Connection realConnection = pooledConnection.getRealConnection();
                    try {
                        realConnection.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        synchronized (lock) {
            closePool.accept(activeConnections);
            closePool.accept(idleConnections);
        }
    }

    @Override
    protected void finalize() throws Throwable {
        closeAll();
        super.finalize();
    }

    @Override
    public Connection getConnection() throws SQLException {
        return borrowConnection(this.username, this.password);
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return borrowConnection(username, password);
    }

}
  • 池化连接
/**
 * 池化连接,Connection的代理
 */
class PooledConnection implements InvocationHandler {

    /** 真实连接 */
    private Connection realConnection;

    /** 代理连接 */
    private Connection proxyConnection;

    /** 连接有效状态 */
    private boolean valid;

    /** 所属连接池 */
    private ConnectionPool connectionPool;

    PooledConnection(Connection realConnection, ConnectionPool connectionPool) {
        this.realConnection = realConnection;
        this.connectionPool = connectionPool;
        this.proxyConnection = (Connection) Proxy.newProxyInstance(Connection.class.getClassLoader(),
            new Class<?>[]{Connection.class}, this);
    }

    public Connection getRealConnection() {
        return realConnection;
    }

    public Connection getProxyConnection() {
        return proxyConnection;
    }

    /**
     * 检查连接是否有效
     */
    public boolean isValid() {
        return valid && connectionPool.pingConnection(realConnection);
    }

    /**
     * 置为无效
     */
    public void invalidate() {
        this.valid = false;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("close")) {
            // 拦截close方法:关闭连接 -> 返还到连接池
            connectionPool.returnConnection(this);
            return null;
        } else {
            return method.invoke(realConnection, args);
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof PooledConnection) {
            return realConnection.hashCode() == ((PooledConnection) obj).realConnection.hashCode();
        } else if (obj instanceof Connection) {
            return realConnection.hashCode() == obj.hashCode();
        } else {
            return false;
        }
    }

}

猜你喜欢

转载自blog.csdn.net/weixin_34114823/article/details/86938781