简单数据库连接池实现(1)---使用动态代理绑定连接

由于一般使用的是标准的JDBC Connection,程序员由于编程习惯,可能会习惯性的调用close方法关闭连接。这样一来连接无法得到重用,数据库连接池机制形同虚设。解决这个问题的好的办法是使用Dynamic Proxy模式。

 

通过实现一个绑定到Connection对象的InvocationHandler接口实现,我们可以在Connection.close方法被调用时将其截获,并以我们自己实现的close方法将其替代,使连接返回到连接池等待下次重用,而不是直接关闭。 

(这段话来自《深入浅出Hibernate》)

1 动态代理绑定类------将动态代理绑定到连接,截取close方法,替换成连接池的回收连接方法(将连接重新放回池中)

 

package cn.kai.datasource_proxy;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.sql.Connection;

 

public class ConnectionHandler implements InvocationHandler {

private Connection realConnection;

private DBConnectionPool pool;

public ConnectionHandler(DBConnectionPool pool) {

this.pool = pool;

}

/**

* 将动态代理绑定到指定Connection

* @param conn

* @return 绑定代理后的Connection

*/

public Connection bind(Connection conn) {

this.realConnection = conn;

Connection proxyConn = (Connection)Proxy.newProxyInstance(

conn.getClass().getClassLoader(),

conn.getClass().getInterfaces(),

this);

return proxyConn;

}

/**

* 方法调用拦截器

* 判断当前调用的方法是否是close方法

* 如是,调用pool.releaseConnectin方法作为标准close方法的替代

* */

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

Object obj = null;

if("close".equals(method.getName())) {

pool.releaseConnection(realConnection);

System.out.println("not really closed");

}else {

obj = method.invoke(realConnection, args);

}

return obj;

}

}

 

2简单连接池代码

package cn.kai.datasource_proxy;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.util.LinkedList;

 

/**

 * 使用了动态代理的简单连接池

 * @author zhangkai

 *

 */

public class DBConnectionPool {

private String url = "jdbc:mysql://localhost:3306/airline_jdbc";

private String username = "root";

private String password = "root";

/* 使用LinkedList作为连接的容器 */

private LinkedList pool = new LinkedList();

 

/** 初始化连接数 */

private static int init_connection_count = 5;

/** 最大连接数 */

private static int max_connection_count = 10;

/** 当前连接数 */

int current_connection_count = 0;

 

public DBConnectionPool() {

for(int i = 0; i < init_connection_count; i++) {

try {

this.pool.addLast(this.createConnection());

this.current_connection_count++;

} catch (Exception e) {

e.printStackTrace();

throw new ExceptionInInitializerError(e);

}

}

}

 

public Connection getConnection() throws Exception {

/*防止并发访问时资源冲突*/

synchronized(pool) {

if(pool.size() > 0) {

return pool.removeFirst();

}

if(this.current_connection_count < max_connection_count) {

this.current_connection_count++;

return this.createConnection();

}

throw new Exception("连接已用尽");

}

}

 

/**释放连接*/

public void releaseConnection(Connection conn) {

if(pool.size() < max_connection_count) {

this.pool.addLast(conn);

}else {

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

 

/**真正创建连接的方法*/

private Connection createConnection() throws Exception {

//在JDBC工具类中加载驱动

Connection conn = DriverManager.getConnection(url,username,password);

ConnectionHandler proxy = new ConnectionHandler(this);

//返回使用了动态代理绑定的连接,在以后关闭该连接时,实际上被放回了连接池

return proxy.bind(conn);

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(持久化/Jdbc/ORM)