动态代理
动态代理的使用
动态代理不用再手动创建代理类
/**
* 类描述:
*
* @ClassName SmDataSource
* @Description TODO
* @Author 小鹏
* @Date 2022/6/2 20:30
* @Version 1.0
*/
public class SmDataSource {
//链表集合
private static LinkedList<Connection> list = new LinkedList<>();
private String url;
private String username;
private String password;
//连接池大小
private Integer initSize;
public SmDataSource(){
}
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//创建数据库连接对象,存入linkedlist中
public void init(){
for (int i = 0; i < initSize; i++) {
try {
Connection connection = DriverManager.getConnection(url, username, password);
/*//创建代理对象 静态代理
Connection connectionProxy = new ConnectionProxy(connection, this);*/
/*
动态代理
*/
ClassLoader classLoader = SmDataSource.class.getClassLoader();
Class[] interfaces = new Class[]{Connection.class};
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
if ("close".equals(name)){
//如果是close方法,则执行我们写的back方法
//执行把connection代理对象放回连接池操作
//proxy就是要归还的connection代理对象,因为是connection代理对象调用了close方法
/**
* 因为connection对象调用了close方法,所以会回调该函数,并把connection自身传给proxy参数
* 所以调用close方法时,会进入SmDataSource对象内部
*
* 因为这个invocationhandler对象就在SmDataSource内部,invoke方法也在SMDataSource内部
* 所以,invoke内部可以直接调用SmDataSource的方法back()
*/
back((Connection) proxy);
}
else{
//如果不是则执行被代理对象原来的方法
return method.invoke(connection,args);
}
return null;
}
};
Connection connectionProxy =(Connection) Proxy.newProxyInstance(classLoader, interfaces,handler);
list.add(connectionProxy);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public Connection getConn(){
//弹出一个数据库连接池对象
return list.pop();
}
/**
* 需要执行的close方法
*/
public void back(Connection connection) {
//需要接收一个待关闭的connection对象
list.addLast(connection);
}
//获取数据库连接池大小
public int getSize(){
return list.size();
}
测试类
public class TextProxy {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//设置虚拟机参数,保存生成的代理对象
System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles","true");
SmDataSource smDataSource = new SmDataSource();
smDataSource.setInitSize(10);
smDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/704a");
smDataSource.setUsername("root");
smDataSource.setPassword("root");
//执行数据库连接池初始化方法
smDataSource.init();
System.out.println("数据库连接池大小:"+smDataSource.getSize());
//获取数据库连接对象
Connection conn = smDataSource.getConn();
PreparedStatement ps = conn.prepareStatement("select * from sys_user where id = ?");
ps.setInt(1,1);
ResultSet resultSet = ps.executeQuery();
resultSet.next();
String uname = resultSet.getString("uname");
System.out.println(uname);
conn.close();
System.out.println("数据库连接池大小:"+smDataSource.getSize());
}
}

浙公网安备 33010602011771号