您的位置:首页 > 编程语言

学习笔记之 自定义连接池实现代码

2014-05-28 00:04 519 查看
package cn.itcast.a_mypool;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

/**
* 自定义连接池
*
* @author Administrator
*
*/
public class PoolDemo {
// 数据库连接信息
private String driverName = "com.mysql.jdbc.Driver";
private String url = "jdbc:mysql:///day17";
private String user = "root";
private String password = "root";

// 当前连接数
private int current_count = 0;
// 初始化连接
private int init_count = 3;
// 最大连接数
private int max_count = 6;

// 保存连接的集合 (连接池)
private LinkedList<Connection> pool = new LinkedList<Connection>();

public PoolDemo() {
// 初始化3个连接
for (int i = 0; i < init_count; i++) {
// 创建连接,放入集合(连接池)
pool.addLast(this.createConnection());
// 当前连接 +1
this.current_count++;
}
}

// 1. 创建连接
private Connection createConnection() {
// 保存代理对象
Connection proxy = null;
try {
// 加载驱动
Class.forName(driverName);
// con相关于目标对象, 要求要创建目标对象的代理对象
final Connection con = DriverManager.getConnection(url, user,
password);
// 创建代理对象
proxy = (Connection) Proxy.newProxyInstance(this.getClass()
.getClassLoader(), // 类加载器
new Class[] { Connection.class }, // 代理对象的接口
// 每当执行代理对象接口中的方法的时候,(反射)自动调用处理器中的invoke方法, 传入参数信息
new InvocationHandler() {
// 方法返回值
Object returnValue = null;

// 第一个参数: 代理对象
// 第二个参数: 调用目标方法(接口中方法)的方法类型
// 第三个参数: 参数值
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {

// 目标:检测close方法的调用,当执行close方法的时候,往连接池中添加连接

// 获取当前执行接口中方法的方法名称
String methodName = method.getName();
// 检测close方法执行
if ("close".equals(methodName)) {
pool.add(con); // 当调用close方法时候,把连接放入连接池
System.out
.println("检测到close方法执行,当前连接已经放入连接中了!");
} else {
// 其他方法执行执行
returnValue = method.invoke(proxy, args);
}

return returnValue;
}
});

} catch (Exception e) {
throw new RuntimeException();
}

return proxy;
}

// 2. 获取连接
public Connection getConnection() {
// 思路:从连接池中获取连接;如果连接池中已经没有连接了, 当前连接数 < 最大, 创建新的连接
// 如果连接池中已经没有连接了,当前连接 >=最大, 不创建新的连接,抛出异常

synchronized (driverName) {
// 1. 如果连接池中有连接,获取连接
if (pool.size() > 0) {
return pool.removeFirst();
}
// 2. 连接池中没有连接
// 2.1 如果当前连接没有达到最大连接,创建连接, 当前连接+1
if (this.current_count < this.max_count) {
this.current_count++;
return this.createConnection();
}
}
// 2.2 连接已经达到最大连接数
throw new RuntimeException("连接已经达到最大连接数,获取连接失败!");
}

// 3. 关闭连接
public void closeConnection(Connection con) {
// 先判断连接池中连接数是否达到最大连接数, 如果没有把连接放入连接池中, 否则关闭

if (pool.size() < this.max_count) {
this.pool.add(con);// 把连接放入连接池
} else {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) throws SQLException {
PoolDemo demo = new PoolDemo();
System.out.println("当前连接:" + demo.init_count);
System.out.println("最大连接:" + demo.max_count);
System.out.println("连接池连接数:" + demo.pool.size());
System.out.println("---------------------");

demo.getConnection();
demo.getConnection();
demo.getConnection();

demo.getConnection();
demo.getConnection();
Connection con = demo.getConnection();

// 回收连接
// demo.closeConnection(con);
con.close();// 关闭连接时候,没有吧连接放入连接池, 没有执行:this.pool.add(con);

demo.getConnection();

System.out.println("当前连接:" + demo.current_count);
System.out.println("连接池连接数:" + demo.pool.size());

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: