大家都知道,在实际应用开发中都会用到数据库。要用数据库我们就必须和数据取得连接,否则一切都是空谈,我想这个没有什么好多说的。正因如此问题就出来了,和数据库取得连接是比较耗资源,而一个网站每天的访问量也是惊人的,想一想如果客户端每向服务器发送一个请求服器就要进行打开连接和关闭连接的工作,这样做明显是不合理,在实际开发中如果是这样去实现数据的持久化真是不可思议。所以引入了连接池的概念,所谓连接池就是当用完一个连接后不是将连接直接关闭而是将它放入到一个容器中缓存放起来,下次再用的时候就直接在容器中取,从而初实现连接的重用。
1:连接池实现类
  1 package net.vicp.jiasoft.dpcp.connectionpool;
package net.vicp.jiasoft.dpcp.connectionpool;
  2
  3 import java.sql.Connection;
import java.sql.Connection;
  4 import java.sql.DriverManager;
import java.sql.DriverManager;
  5 import java.sql.SQLException;
import java.sql.SQLException;
  6 import java.util.Vector;
import java.util.Vector;
  7 import net.vicp.jiasoft.dpcp.dynaproxy.ConnectionProxy;
import net.vicp.jiasoft.dpcp.dynaproxy.ConnectionProxy;
  8 import net.vicp.jiasoft.dpcp.util.PropertiesUtil;
import net.vicp.jiasoft.dpcp.util.PropertiesUtil;
  9
 10
 /** *//**
/** *//**
 11 * @author Jak.Shen
 * @author Jak.Shen
 12 * 日期:2008-3-31
 * 日期:2008-3-31
 13 * 说明:连接池实现类
 * 说明:连接池实现类
 14 */
 */
 15
 16
 public class ConnectionPool
public class ConnectionPool  {
{
 17
 18 private static ConnectionPool connectionPool;//自身静态成员变量,用于实现单例.
    private static ConnectionPool connectionPool;//自身静态成员变量,用于实现单例.
 19 private static Vector connPool;//连接缓存容器
    private static Vector connPool;//连接缓存容器
 20 private int poolMaxSize = 10;//连接池最大缓存数
    private int poolMaxSize = 10;//连接池最大缓存数
 21 private String userName;//连接用户名
    private String userName;//连接用户名
 22 private String password;//连接密码
    private String password;//连接密码
 23 private String driverClass;//连接驱动
    private String driverClass;//连接驱动
 24 private String url;//连接字符串
    private String url;//连接字符串
 25
 26
 /** *//**
    /** *//**
 27 * 私有构造方法,初始化变量.并心预填充连接池。
     * 私有构造方法,初始化变量.并心预填充连接池。
 28 */
     */
 29
 private ConnectionPool()
    private ConnectionPool()  {
{
 30 String temp = PropertiesUtil.getValueByKey("poolMaxSize");
        String temp = PropertiesUtil.getValueByKey("poolMaxSize");
 31
 if (temp != null)
        if (temp != null)  {
{
 32 poolMaxSize = Integer.parseInt(temp);
            poolMaxSize = Integer.parseInt(temp);
 33 }
        }
 34 userName = PropertiesUtil.getValueByKey("userName");
        userName = PropertiesUtil.getValueByKey("userName");
 35 password = PropertiesUtil.getValueByKey("password");
        password = PropertiesUtil.getValueByKey("password");
 36 driverClass = PropertiesUtil.getValueByKey("driverClass");
        driverClass = PropertiesUtil.getValueByKey("driverClass");
 37 url = PropertiesUtil.getValueByKey("url");
        url = PropertiesUtil.getValueByKey("url");
 38 connPool = new Vector();
        connPool = new Vector();
 39 int size = 0;
        int size = 0;
 40
 if (poolMaxSize > 5)
        if (poolMaxSize > 5)  {
{
 41 size = 5;
            size = 5;
 42
 } else
        } else  {
{
 43 size = poolMaxSize;
            size = poolMaxSize;
 44 }
        }
 45
 for (int i = 0; i < size; i++)
        for (int i = 0; i < size; i++)  {
{
 46 connPool.add(createConnection());//预填充连接池
            connPool.add(createConnection());//预填充连接池
 47 }
        }
 48 }
    }
 49
 50
 /** *//**
    /** *//**
 51 * 此方法用于创建并返回连接池对象。
     * 此方法用于创建并返回连接池对象。
 52 * @return
     * @return
 53 */
     */
 54
 public static ConnectionPool newInstance()
    public static ConnectionPool newInstance()  {
{
 55
 if (connectionPool == null)
        if (connectionPool == null)  {
{
 56 connectionPool = new ConnectionPool();
            connectionPool = new ConnectionPool();
 57 }
        }
 58 return connectionPool;
        return connectionPool;
 59 }
    }
 60
 61
 /** *//**
    /** *//**
 62 * 此方法用于创建一个连接。
     * 此方法用于创建一个连接。
 63 * @return
     * @return
 64 */
     */
 65
 private Connection createConnection()
    private Connection createConnection()  {
{
 66 Connection connection = null;
        Connection connection = null;
 67
 try
        try  {
{
 68 Class.forName(driverClass);
            Class.forName(driverClass);
 69
 } catch (ClassNotFoundException e)
        } catch (ClassNotFoundException e)  {
{
 70 e.printStackTrace();
            e.printStackTrace();
 71 }
        }
 72
 try
        try  {
{
 73 connection = DriverManager.getConnection(url, userName, password);
            connection = DriverManager.getConnection(url, userName, password);
 74
 } catch (SQLException e)
        } catch (SQLException e)  {
{
 75 e.printStackTrace();
            e.printStackTrace();
 76 }
        }
 77 return connection;
        return connection;
 78 }
    }
 79
 80
 /** *//**
    /** *//**
 81 * 此方法用于将用完的连接放入池中。
     * 此方法用于将用完的连接放入池中。
 82 */
     */
 83
 public static synchronized void releaseConnection(Connection connection)
    public static synchronized void releaseConnection(Connection connection)  {
{
 84 connPool.add(connection);
        connPool.add(connection);
 85 }
    }
 86
 87
 /** *//**
    /** *//**
 88 * 此方法用于返回一个连接。
     * 此方法用于返回一个连接。
 89 * @return
     * @return
 90 */
     */
 91
 public synchronized Connection getConnection()
    public synchronized Connection getConnection()  {
{
 92 // 要防止直接关闭连接因此需要对Connection的close()方法进行拦截
        // 要防止直接关闭连接因此需要对Connection的close()方法进行拦截
 93 // 所以需要要给Connection接口动态加入代理,getConnection()是加入代理的好地方法
        // 所以需要要给Connection接口动态加入代理,getConnection()是加入代理的好地方法
 94 // connectionProxy是动态代理对象
        // connectionProxy是动态代理对象
 95 ConnectionProxy connectionProxy = new ConnectionProxy();
        ConnectionProxy connectionProxy = new ConnectionProxy();
 96 int size = connPool.size();
        int size = connPool.size();
 97
 if (connPool.size() == 0 || size < poolMaxSize)
        if (connPool.size() == 0 || size < poolMaxSize)  {
{
 98 connectionProxy.setConnection(createConnection());
            connectionProxy.setConnection(createConnection());
 99 return connectionProxy.proxyBind();
            return connectionProxy.proxyBind();
100 }
        }
101 Connection connection = (Connection) connPool.get(size - 1);
        Connection connection = (Connection) connPool.get(size - 1);
102 connectionProxy.setConnection(connection);
        connectionProxy.setConnection(connection);
103 connPool.remove(size - 1);
        connPool.remove(size - 1);
104 return connectionProxy.proxyBind();
        return connectionProxy.proxyBind();
105 }
    }
106 }
}
107
 
2:动态代理类
 1 package net.vicp.jiasoft.dpcp.dynaproxy;
package net.vicp.jiasoft.dpcp.dynaproxy;
 2
 3 import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
import java.lang.reflect.Proxy;
 6 import java.sql.Connection;
import java.sql.Connection;
 7 import net.vicp.jiasoft.dpcp.connectionpool.ConnectionPool;
import net.vicp.jiasoft.dpcp.connectionpool.ConnectionPool;
 8
 9
 /** *//**
/** *//** 
10 * @author Jak.Shen
 * @author Jak.Shen
11 * 日期:2008-3-31
 * 日期:2008-3-31
12 * 说明:动态代理实类,实现InvocationHandler接口就可以成为动态代理了.要注意的是只能对接口代理。
 * 说明:动态代理实类,实现InvocationHandler接口就可以成为动态代理了.要注意的是只能对接口代理。
13 */
 */
14 
 
15
 public class ConnectionProxy implements InvocationHandler
public class ConnectionProxy implements InvocationHandler  {
{
16
17 private Connection connection;//动态代理的对象
    private Connection connection;//动态代理的对象
18
19
 public ConnectionProxy()
    public ConnectionProxy()  {
{
20 }
    }
21
22
 public ConnectionProxy(Connection connection)
    public ConnectionProxy(Connection connection)  {
{
23 this.connection = connection;
        this.connection = connection;
24 }
    }
25
26
 /** *//**
    /** *//**
27 * 重写实现InvocationHandler方法invoke()。
     * 重写实现InvocationHandler方法invoke()。
28 * 此处注意@Override标注在JDK1.6中才支持,JDK1.6以下版本请将@Override标注去掉。
     * 此处注意@Override标注在JDK1.6中才支持,JDK1.6以下版本请将@Override标注去掉。
29 */
     */
30 @Override
    @Override
31 public Object invoke(Object proxy, Method method, Object[] args)
    public Object invoke(Object proxy, Method method, Object[] args)
32
 throws Throwable
            throws Throwable  {
{
33 // 如果方法是close(),就替换成连接池的releaseConnection()方法.
        // 如果方法是close(),就替换成连接池的releaseConnection()方法.
34
 if (method.getName().equals("close"))
        if (method.getName().equals("close"))  {
{
35 System.out.println("before invoke !");
            System.out.println("before invoke !");
36 ConnectionPool.releaseConnection(connection);
            ConnectionPool.releaseConnection(connection);
37 System.out.println("after invoke !");
            System.out.println("after invoke !");
38
 } else
        } else  {
{
39 // 对非close()方法,不做处理,直接调用.
            // 对非close()方法,不做处理,直接调用.
40 return method.invoke(connection, args);
            return method.invoke(connection, args);
41 }
        }
42 return null;
        return null;
43 }
    }
44
45
 /** *//**
    /** *//**
46 * 绑定要进行代理的对象
     * 绑定要进行代理的对象
47 * @return
     * @return
48 */
     */
49
 public Connection proxyBind()
    public Connection proxyBind()  {
{
50 // 返回一个指定接口的代理类实例
        // 返回一个指定接口的代理类实例
51 // newProxyInstance() arg0-->定义代理类的类加载器
        // newProxyInstance() arg0-->定义代理类的类加载器
52 // newProxyInstance() arg1-->代理类要实现的接口列表
        // newProxyInstance() arg1-->代理类要实现的接口列表
53 // newProxyInstance() arg2-->指派方法调用的调用处理程序(此处就是去调用this对象的invoke())
        // newProxyInstance() arg2-->指派方法调用的调用处理程序(此处就是去调用this对象的invoke())
54 Connection proxyConnection = (Connection) Proxy.newProxyInstance(
        Connection proxyConnection = (Connection) Proxy.newProxyInstance(
55 connection.getClass().getClassLoader(), connection.getClass()
                connection.getClass().getClassLoader(), connection.getClass()
56 .getInterfaces(), this);
                        .getInterfaces(), this);
57 return proxyConnection;
        return proxyConnection;
58 }
    }
59
60
 public Connection getConnection()
    public Connection getConnection()  {
{
61 return connection;
        return connection;
62 }
    }
63
64
 public void setConnection(Connection connection)
    public void setConnection(Connection connection)  {
{
65 this.connection = connection;
        this.connection = connection;
66 }
    }
67 }
}
68
 
3:属性文件操作工具类
 1 package net.vicp.jiasoft.dpcp.util;
package net.vicp.jiasoft.dpcp.util;
 2
 3 import java.io.FileInputStream;
import java.io.FileInputStream;
 4 import java.io.FileNotFoundException;
import java.io.FileNotFoundException;
 5 import java.io.IOException;
import java.io.IOException;
 6 import java.util.Properties;
import java.util.Properties;
 7
 8
 /** *//**
/** *//** 
 9 * @author Jak.Shen
 * @author Jak.Shen
10 * 日期:2008-3-31
 * 日期:2008-3-31
11 * 说明:属性文件操作工具类
 * 说明:属性文件操作工具类
12 */
 */
13
14
 public class PropertiesUtil
public class PropertiesUtil  {
{
15 private static Properties properties = new Properties();
    private static Properties properties = new Properties();
16 private static FileInputStream fileInputStream;
    private static FileInputStream fileInputStream;
17
18
 /** *//**
    /** *//**
19 * 从属性文件中根据Key取值
     * 从属性文件中根据Key取值
20 * @param key
     * @param key
21 * @return
     * @return
22 */
     */
23
 public static String getValueByKey(String key)
    public static String getValueByKey(String key)  {
{
24
 if (fileInputStream == null)
        if (fileInputStream == null)  {
{
25
 try
            try  {
{
26 fileInputStream = new FileInputStream("src/dpcp.properties");
                fileInputStream = new FileInputStream("src/dpcp.properties");
27
 } catch (FileNotFoundException e)
            } catch (FileNotFoundException e)  {
{
28 e.printStackTrace();
                e.printStackTrace();
29 }
            }
30 }
        }
31
 try
        try  {
{
32 properties.load(fileInputStream);
            properties.load(fileInputStream);
33
 } catch (IOException e)
        } catch (IOException e)  {
{
34 e.printStackTrace();
            e.printStackTrace();
35 }
        }
36 return properties.get(key).toString();
        return properties.get(key).toString();
37 }
    }
38 }
}
39
 
4:测试客户端
 1 package net.vicp.jiasoft.dpcp.client;
package net.vicp.jiasoft.dpcp.client;
 2
 3 import java.sql.Connection;
import java.sql.Connection;
 4 import java.sql.SQLException;
import java.sql.SQLException;
 5 import net.vicp.jiasoft.dpcp.connectionpool.ConnectionPool;
import net.vicp.jiasoft.dpcp.connectionpool.ConnectionPool;
 6
 7
 /** *//**
/** *//** 
 8 * @author Jak.Shen
 * @author Jak.Shen
 9 * 日期:2008-3-31
 * 日期:2008-3-31
10 * 说明:动态代理连接池测试客户端
 * 说明:动态代理连接池测试客户端
11 */
 */
12
 public class DbPoolClient
public class DbPoolClient  {
{
13
14
 public static void main(String[] args)
    public static void main(String[] args)  {
{
15 ConnectionPool connectionPool = ConnectionPool.newInstance();
        ConnectionPool connectionPool = ConnectionPool.newInstance();
16 Connection connection = connectionPool.getConnection();
        Connection connection = connectionPool.getConnection();
17
 try
        try  {
{
18 connection.close();
            connection.close();
19
 } catch (SQLException e)
        } catch (SQLException e)  {
{
20 e.printStackTrace();
            e.printStackTrace();
21 }
        }
22 }
    }
23 }
}
24
 
5:属性配置文件(dpcp.properties)
 1 #最大连接数
#最大连接数
 2 poolMaxSize=4
poolMaxSize=4
 3 #连接用户名
#连接用户名
 4 userName=scott
userName=scott
 5 #连接密码
#连接密码
 6 password=tiger
password=tiger
 7 #连接驱动
#连接驱动
 8 driverClass=oracle.jdbc.driver.OracleDriver
driverClass=oracle.jdbc.driver.OracleDriver
 9 #连接字符串
#连接字符串
10 url=jdbc:oracle:thin:@localhost:1521:ACCP
url=jdbc:oracle:thin:@localhost:1521:ACCP 
源码下载 -- (ConnectionPool.rar) 
 杰森 
邮箱:json.shen(at)gmail.com
网站:www.shenjia.org
	posted on 2008-03-31 18:17 
杰森 阅读(2463) 
评论(2)  编辑  收藏  所属分类: 
JavaSE