当前位置:Gxlcms > 数据库问题 > java之使用动态代理实现数据库连接的回收

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

时间:2021-07-01 10:21:17 帮助过:29人阅读

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

3.编写一个测试类

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

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

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

技术分享

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

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

标签:

人气教程排行