JAVA 动态代理(实现自定义数据库连接池)
环境:JDK1.8
MAVEN
IDEA 2018.2
jar包:mysql-connector-java-5.1.38
实现思路:
首先通过资源文件读取数据库连接必要信息(driver,url,user,password),获取数据库连接,然后通过动态代理模式阻止连接真正被关闭而是放回集(连接池)合中。
Maven导包
mysql
mysql-connector-java
5.1.38
项目结构
dbconfig.properties
#数据库驱动配置文件
DRIVER=com.mysql.jdbc.Driver
URL=jdbc:mysql:///abc
USER=root
PASSWORD=abcJDBCUtil.java
package cn.omist.util;
import java.sql.*;
import java.util.ResourceBundle;
/**
* 数据库相关操作
* @author Mr_Fan
*/
public class JDBCUtil {
//使用ResourceBundle读取资源文件
private static ResourceBundle bundle = ResourceBundle.getBundle("dbconfig");
private static String driver;
private static String url;
private static String user;
private static String password;
//使用静态代码块进行赋值
static {
driver = bundle.getString("DRIVER");
url = bundle.getString("URL");
user = bundle.getString("USER");
password = bundle.getString("PASSWORD");
}
/**
* 获取连接
* @return
*/
public static Connection getConnection() {
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
return conn;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 释放连接
* @param rs
* @param st
* @param conn
*/
public static void release(ResultSet rs, Statement st, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (st != null) {
try {
st.cancel();
} catch (Exception e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}MyDataSource.java
package cn.omist.dataSource;
import cn.omist.util.JDBCUtil;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 自定义连接池
*
* @author Mr_Fan
*/
public class MyDataSource {
//定义一个池,用于存放连接
// private static List pool = new ArrayList(); //线程不安全所以不使用
//Collections.synchronixzedList 方法使集合变得线程安全
private static List pool = Collections.synchronizedList(new ArrayList());
//使用静态代码快递给池中加入连接
static {
for (int i &#61; 0; i <10; i&#43;&#43;) {
Connection conn &#61; JDBCUtil.getConnection();
pool.add(conn);
}
}
/**
* 获取一个连接 采用动态代理模式
*
* &#64;return
*/
public static Connection getConnection() {
final Connection conn &#61; pool.remove(0);
//创建代理对象
Connection proxyConn &#61; (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(),
conn.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object rtValue &#61; null;
//1.判断当前方法是不是close方法
if ("close".equals(method.getName())) {
//不能直接关闭
pool.add(conn);//返回池中
} else {
rtValue &#61; method.invoke(conn, args);
}
return rtValue;
}
});
return proxyConn;
}
/**
* 获取池中的连接数
*
* &#64;return
*/
public static int getPoolSize() {
return pool.size();
}
}DataSourceTest.java
package cn.omist.test;
import cn.omist.dataSource.MyDataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class DataSourceTest {
public static void main(String[] args) throws SQLException {
int size &#61; MyDataSource.getPoolSize();
System.out.println("使用之前连接数量:"&#43;size);
for (int i &#61; 0; i <10; i&#43;&#43;) {
Connection conn &#61; MyDataSource.getConnection();
System.out.println(conn);
conn.close();
}
int size1 &#61; MyDataSource.getPoolSize();
System.out.println("使用之后连接数量:"&#43;size);
}
}运行结果
使用之前连接数量:10
com.mysql.jdbc.JDBC4Connection&#64;3d82c5f3
com.mysql.jdbc.JDBC4Connection&#64;2b05039f
com.mysql.jdbc.JDBC4Connection&#64;61e717c2
com.mysql.jdbc.JDBC4Connection&#64;66cd51c3
com.mysql.jdbc.JDBC4Connection&#64;4dcbadb4
com.mysql.jdbc.JDBC4Connection&#64;4e515669
com.mysql.jdbc.JDBC4Connection&#64;17d10166
com.mysql.jdbc.JDBC4Connection&#64;1b9e1916
com.mysql.jdbc.JDBC4Connection&#64;ba8a1dc
com.mysql.jdbc.JDBC4Connection&#64;4f8e5cde
使用之后连接数量:10
支付宝扫一扫
微信扫一扫
企鹅扫一扫