自定义连接池(管理连接)
代码实现:
1. MyPool.java 连接池类,
2. 指定全局参数: 初始化数目、最大连接数、当前连接、 连接池集合
3. 构造函数:循环创建3个连接
4. 写一个创建连接的方法
5. 获取连接
------> 判断: 池中有连接, 直接拿
------> 池中没有连接,
-------> 判断,是否达到最大连接数; 达到,抛出异常;没有达到最大连接数,
创建新的连接
6. 释放连接
如何对Connection对象,生成一个代理对象:
|--java.lang.reflect.Proxy
static Object newProxyInstance(
ClassLoader loader, 当前使用的类加载器
Class<?>[] interfaces, 目标对象(Connection)实现的接口类型
InvocationHandler h 事件处理器:当执行上面接口中的方法的时候,就会自动触发事件处理器代码,把当前执行的方法(method)作为参数传入。
)
代理的总结:(了解会用)
使用代理,可以在不实现接口的情况,对接口的方法进行扩展,添加额外的用户需要的业务逻辑!
Demo
package com.cn.pool;
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:Liu Zhiyong
* Version:Version_1
* Date:2017年4月10日19:25:03
* Desc:自定义连接池, 管理连接
代码实现:
1. MyPool.java 连接池类,
2. 指定全局参数: 初始化数目、最大连接数、当前连接、 连接池集合
3. 构造函数:循环创建3个连接
4. 写一个创建连接的方法
5. 获取连接
------> 判断: 池中有连接, 直接拿
------> 池中没有连接,
-------> 判断,是否达到最大连接数; 达到,抛出异常;没有达到最大连接数,
创建新的连接
6. 释放连接
-------> 连接放回集合中(..)
*/
public class MyPool {
private int initCount = 3;//初始化连接数据
private int maxCount = 6;//最大连接数
private int currentCount = 0;//记录当前连接数
//连接池(存放所有的初始化连接 )
private LinkedList<Connection> pool = new LinkedList<Connection>();
/**
* 1.构造函数中,初始化连接放入连接池
*/
public MyPool(){
//初始化连接
for(int i=0; i<initCount; i++){
//记录当前连接
currentCount++;
//把连接加入连接池
pool.add(this.createConnection());
}
}
/**
* 2.创建一个新的连接的方法(代理)
* @return
*/
private Connection createConnection(){
try {
//加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
//原始的目标对象
final Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
/*****************对Connection对象代理***********************/
//对conn创建其代理对象。返回一个指定接口的代理类实例
Connection proxy = (Connection)Proxy.newProxyInstance(
conn.getClass().getClassLoader(),// 定义代理类的类加载器。负责加载类的对象。
new Class[]{Connection.class},//代理类要实现的接口列表
new InvocationHandler(){// 当调用con对象方法的时候, 自动触发事务处理器
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
//方法返回
Object result = null;
// 当前执行的方法的方法名
String methodName = method.getName();
if("close".equals(methodName)){
//连接放入连接池
pool.add(conn);
}else{
result = method.invoke(conn, args); 调用目标对象方法
}
return result;
}
}//指派方法调用的调用处理程序
);
return proxy;//返回代理对象
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 3.获取连接
* @return
*/
public Connection getConnection(){
//3.1 判断连接池中是否有连接,如果有连接,就直接从连接池取出
if(!pool.isEmpty()){
return pool.removeFirst();//删除一个,并返回删除的对象Connection
}
//3.2连接池中没有连接:判断,如果没有达到最大连接数,创建
if(currentCount < maxCount){
//记录当前使用的连接数
currentCount++;
//创建连接
return this.createConnection();
}
//3.3如果当前已经达到最大连接数,抛出异常
throw new RuntimeException("当前连接已经达到最大连接数目");
}
/**
* 4.释放连接(手动释放)
*/
public void realeaseConnection(Connection conn){
//4.1 判断,池的数目如果小于初始化连接,就放入池中
if(pool.size() < initCount){
pool.addLast(conn);
}else{
//4.2关闭
try {
currentCount--;//当前连接数-1
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws SQLException {
MyPool pool = new MyPool();
System.out.println("连接池:" + pool.pool.size() + "当前连接:" + pool.currentCount);
//使用连接
Connection conn1 = pool.getConnection();
System.out.println("连接池:" + pool.pool.size() + "当前连接:" + pool.currentCount);
Connection conn2 = pool.getConnection();
System.out.println("连接池:" + pool.pool.size() + "当前连接:" + pool.currentCount);
Connection conn3 = pool.getConnection();
System.out.println("连接池:" + pool.pool.size() + "当前连接:" + pool.currentCount);
Connection conn4 = pool.getConnection();
System.out.println("连接池:" + pool.pool.size() + "当前连接:" + pool.currentCount);
Connection conn5 = pool.getConnection();
System.out.println("连接池:" + pool.pool.size() + "当前连接:" + pool.currentCount);
Connection conn6 = pool.getConnection();
System.out.println("连接池:" + pool.pool.size() + "当前连接:" + pool.currentCount);
//释放连接,连接放回连接池
// pool.realeaseConnection(conn1);
/*
希望:当关闭连接的时候,要把连接放入连接池!【当调用Connection接口的close方法时候,希望触发pool.addLast(con);操作】
把连接放入连接池
解决1:实现Connection接口,重写close方法
解决2:动态代理
*/
conn6.close();
System.out.println("连接池:" + pool.pool.size() + "当前连接:" + pool.currentCount);
//再获取
pool.getConnection();
}
}