java之使用动态代理实现数据库连接的回收

1.编写一个管理数据库连接类

 1 package cn.mycast.bank.db;
 2  3 import java.sql.Connection;
 4 import java.sql.SQLException;
 5 import java.util.LinkedList;
 6 import cn.mycast.bank.util.JdbcUtil;
 7 public class MyDatabasePool {
 8     LinkedList<Connection> connPool=new LinkedList<Connection>();//存放连接
 9     private int Maxsize=10;
10     private int Initsize=6;
11     int Currentsize=0;
12     public MyDatabasePool(){
13         for(int i=0;i<Initsize;i++)//连接池中存放10个连接
14         {
15             this.connPool.addLast(this.CreateConnection());//每次添加到集合最后面
16             this.Currentsize++;
17         }
18     }
19     public Connection CreateConnection(){//获得连接
20         Connection realconn=JdbcUtil.getConnection();
21         MyDatabaseHandler handler=new MyDatabaseHandler(this);//代理类
22         return handler.bind(realconn);
23     }
24     public Connection GetConnection() throws SQLException{
25         synchronized(connPool){
26             if(this.connPool.size()>0){
27                 return connPool.removeFirst();//取出最上面的一个连接
28             }
29             if(this.Currentsize<Maxsize){
30                 this.Currentsize++;
31                 return this.CreateConnection();
32             }
33             throw new SQLException("");
34         }
35     }
36     public void FreeConnection(Connection conn){//将用完后的连接放回到集合中
37         this.connPool.addLast(conn);
38     }
39 }

2.编写一个代理类,这里主要是实现一个InvocationHandler的接口

 1 package cn.mycast.bank.db;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 import java.sql.Connection;
 7 public class MyDatabaseHandler implements InvocationHandler{
 8     private Connection realConnection;
 9     private Connection WrapperConn;
10     private MyDatabasePool databasesource;
11     private int Maxsize=10;
12     int Currentsize=0;
13     public MyDatabaseHandler(MyDatabasePool databasesource){
14         this.databasesource=databasesource;
15     }
16     /*
17      * Proxy类动态根据这里我们制定的接口生成一个class byte,然后通过classloader将class byte生成一个类对象,再将该对象委派给当前代理类的实例
18      */
19     Connection bind(Connection realConn){
20         this.realConnection=realConn;//需要代理的原始的对象
21         this.WrapperConn=(Connection)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{Connection.class}, this);
22         return WrapperConn;
23         //这步是创建代理对象了,第一个参数指定类加载器:使得这个代理类能访问被代理对象,
24         //第二个参数指定代理类应该具有哪些接口:要不然怎么去代理被代理对象,
25         //第二个参数就是指定,代理对象额外完成的业务逻辑了:如前面所述的获取被代理类的执行时间。
26     }
27     @Override
28     public Object invoke(Object proxy, Method method, Object[] args)
29             throws Throwable {
30         if("close".equals(method.getName())){//这里代理原始类的close方法
31             this.Currentsize++;
32             if(this.Currentsize<this.Maxsize){
33                 this.databasesource.connPool.addLast(this.WrapperConn);
34             }else{
35                 this.realConnection.close();
36                 this.databasesource.Currentsize--;
37             }
38         }
39         return method.invoke(this.realConnection, args);
40     }
41     
42 }

3.编写一个测试类

 1 package cn.mycast.bank.db;
 2 
 3 import java.sql.Connection;
 4 import java.sql.SQLException;
 5 
 6 public class Main {
 7     /**
 8      * @param args
 9      * @throws SQLException 
10      */
11     public static void main(String[] args) {
12         System.out.println("创建连接..........");
13         MyDatabasePool databasepool=new MyDatabasePool();
14         
15         System.out.println("客户端连接..........");
16         Connection conn=null;
17         try {
18             conn=databasepool.GetConnection();
19             System.out.println("連接池中的連接個數"+databasepool.connPool.size());
20         } catch (SQLException e) {
21             // TODO Auto-generated catch block
22             e.printStackTrace();
23         }finally{
24             if(conn!=null){
25                 try {
26                     conn.close();
27                     System.out.println("客户端關閉連接..........");
28                 } catch (SQLException e) {
29                     e.printStackTrace();
30                 }
31             }
32         }
33         System.out.println("連接池中的連接個數"+databasepool.connPool.size());
34     }
35 
36 }

创建连接..........
客户端连接..........
連接池中的連接個數5
客户端關閉連接..........
連接池中的連接個數6

动态代理工作原理图如下:

      动态代理就是对被代理的类进行一次封装包裹,以便加上我们自己需要加的一些业务逻辑。

转载于:https://www.cnblogs.com/jameszbp/p/4498648.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值