Chinese To English     英文 轉(zhuǎn) 中文             
                   
          隨筆-27  評(píng)論-53  文章-0  trackbacks-0

                  大家都知道,在實(shí)際應(yīng)用開發(fā)中都會(huì)用到數(shù)據(jù)庫(kù)。要用數(shù)據(jù)庫(kù)我們就必須和數(shù)據(jù)取得連接,否則一切都是空談,我想這個(gè)沒有什么好多說(shuō)的。正因如此問題就出來(lái)了,和數(shù)據(jù)庫(kù)取得連接是比較耗資源,而一個(gè)網(wǎng)站每天的訪問量也是驚人的,想一想如果客戶端每向服務(wù)器發(fā)送一個(gè)請(qǐng)求服器就要進(jìn)行打開連接和關(guān)閉連接的工作,這樣做明顯是不合理,在實(shí)際開發(fā)中如果是這樣去實(shí)現(xiàn)數(shù)據(jù)的持久化真是不可思議。所以引入了連接池的概念,所謂連接池就是當(dāng)用完一個(gè)連接后不是將連接直接關(guān)閉而是將它放入到一個(gè)容器中緩存放起來(lái),下次再用的時(shí)候就直接在容器中取,從而初實(shí)現(xiàn)連接的重用。

          1:連接池實(shí)現(xiàn)類

            1package net.vicp.jiasoft.dpcp.connectionpool;
            2
            3import java.sql.Connection;
            4import java.sql.DriverManager;
            5import java.sql.SQLException;
            6import java.util.Vector;
            7import net.vicp.jiasoft.dpcp.dynaproxy.ConnectionProxy;
            8import net.vicp.jiasoft.dpcp.util.PropertiesUtil;
            9
           10/**
           11 * @author Jak.Shen
           12 * 日期:2008-3-31
           13 * 說(shuō)明:連接池實(shí)現(xiàn)類
           14 */

           15
           16public class ConnectionPool {
           17
           18    private static ConnectionPool connectionPool;//自身靜態(tài)成員變量,用于實(shí)現(xiàn)單例.
           19    private static Vector connPool;//連接緩存容器
           20    private int poolMaxSize = 10;//連接池最大緩存數(shù)
           21    private String userName;//連接用戶名
           22    private String password;//連接密碼
           23    private String driverClass;//連接驅(qū)動(dòng)
           24    private String url;//連接字符串
           25
           26    /**
           27     * 私有構(gòu)造方法,初始化變量.并心預(yù)填充連接池。
           28     */

           29    private ConnectionPool() {
           30        String temp = PropertiesUtil.getValueByKey("poolMaxSize");
           31        if (temp != null{
           32            poolMaxSize = Integer.parseInt(temp);
           33        }

           34        userName = PropertiesUtil.getValueByKey("userName");
           35        password = PropertiesUtil.getValueByKey("password");
           36        driverClass = PropertiesUtil.getValueByKey("driverClass");
           37        url = PropertiesUtil.getValueByKey("url");
           38        connPool = new Vector();
           39        int size = 0;
           40        if (poolMaxSize > 5{
           41            size = 5;
           42        }
           else {
           43            size = poolMaxSize;
           44        }

           45        for (int i = 0; i < size; i++{
           46            connPool.add(createConnection());//預(yù)填充連接池
           47        }

           48    }

           49
           50    /**
           51     * 此方法用于創(chuàng)建并返回連接池對(duì)象。
           52     * @return
           53     */

           54    public static ConnectionPool newInstance() {
           55        if (connectionPool == null{
           56            connectionPool = new ConnectionPool();
           57        }

           58        return connectionPool;
           59    }

           60
           61    /**
           62     * 此方法用于創(chuàng)建一個(gè)連接。
           63     * @return
           64     */

           65    private Connection createConnection() {
           66        Connection connection = null;
           67        try {
           68            Class.forName(driverClass);
           69        }
           catch (ClassNotFoundException e) {
           70            e.printStackTrace();
           71        }

           72        try {
           73            connection = DriverManager.getConnection(url, userName, password);
           74        }
           catch (SQLException e) {
           75            e.printStackTrace();
           76        }

           77        return connection;
           78    }

           79
           80    /**
           81     * 此方法用于將用完的連接放入池中。
           82     */

           83    public static synchronized void releaseConnection(Connection connection) {
           84        connPool.add(connection);
           85    }

           86
           87    /**
           88     * 此方法用于返回一個(gè)連接。
           89     * @return
           90     */

           91    public synchronized Connection getConnection() {
           92        // 要防止直接關(guān)閉連接因此需要對(duì)Connection的close()方法進(jìn)行攔截
           93        // 所以需要要給Connection接口動(dòng)態(tài)加入代理,getConnection()是加入代理的好地方法
           94        // connectionProxy是動(dòng)態(tài)代理對(duì)象
           95        ConnectionProxy connectionProxy = new ConnectionProxy();
           96        int size = connPool.size();
           97        if (connPool.size() == 0 || size < poolMaxSize) {
           98            connectionProxy.setConnection(createConnection());
           99            return connectionProxy.proxyBind();
          100        }

          101        Connection connection = (Connection) connPool.get(size - 1);
          102        connectionProxy.setConnection(connection);
          103        connPool.remove(size - 1);
          104        return connectionProxy.proxyBind();
          105    }

          106}

          107

          2:動(dòng)態(tài)代理類
           1package net.vicp.jiasoft.dpcp.dynaproxy;
           2
           3import java.lang.reflect.InvocationHandler;
           4import java.lang.reflect.Method;
           5import java.lang.reflect.Proxy;
           6import java.sql.Connection;
           7import net.vicp.jiasoft.dpcp.connectionpool.ConnectionPool;
           8
           9/** 
          10 * @author Jak.Shen
          11 * 日期:2008-3-31
          12 * 說(shuō)明:動(dòng)態(tài)代理實(shí)類,實(shí)現(xiàn)InvocationHandler接口就可以成為動(dòng)態(tài)代理了.要注意的是只能對(duì)接口代理。
          13 */

          14 
          15public class ConnectionProxy implements InvocationHandler {
          16
          17    private Connection connection;//動(dòng)態(tài)代理的對(duì)象
          18
          19    public ConnectionProxy() {
          20    }

          21
          22    public ConnectionProxy(Connection connection) {
          23        this.connection = connection;
          24    }

          25
          26    /**
          27     * 重寫實(shí)現(xiàn)InvocationHandler方法invoke()。
          28     * 此處注意@Override標(biāo)注在JDK1.6中才支持,JDK1.6以下版本請(qǐng)將@Override標(biāo)注去掉。
          29     */

          30    @Override
          31    public Object invoke(Object proxy, Method method, Object[] args)
          32            throws Throwable {
          33        // 如果方法是close(),就替換成連接池的releaseConnection()方法.
          34        if (method.getName().equals("close")) {
          35            System.out.println("before invoke !");
          36            ConnectionPool.releaseConnection(connection);
          37            System.out.println("after invoke !");
          38        }
           else {
          39            // 對(duì)非close()方法,不做處理,直接調(diào)用.
          40            return method.invoke(connection, args);
          41        }

          42        return null;
          43    }

          44
          45    /**
          46     * 綁定要進(jìn)行代理的對(duì)象
          47     * @return
          48     */

          49    public Connection proxyBind() {
          50        // 返回一個(gè)指定接口的代理類實(shí)例
          51        // newProxyInstance() arg0-->定義代理類的類加載器
          52        // newProxyInstance() arg1-->代理類要實(shí)現(xiàn)的接口列表
          53        // newProxyInstance() arg2-->指派方法調(diào)用的調(diào)用處理程序(此處就是去調(diào)用this對(duì)象的invoke())
          54        Connection proxyConnection = (Connection) Proxy.newProxyInstance(
          55                connection.getClass().getClassLoader(), connection.getClass()
          56                        .getInterfaces(), this);
          57        return proxyConnection;
          58    }

          59
          60    public Connection getConnection() {
          61        return connection;
          62    }

          63
          64    public void setConnection(Connection connection) {
          65        this.connection = connection;
          66    }

          67}

          68

          3:屬性文件操作工具類
           1package net.vicp.jiasoft.dpcp.util;
           2
           3import java.io.FileInputStream;
           4import java.io.FileNotFoundException;
           5import java.io.IOException;
           6import java.util.Properties;
           7
           8/** 
           9 * @author Jak.Shen
          10 * 日期:2008-3-31
          11 * 說(shuō)明:屬性文件操作工具類
          12 */

          13
          14public class PropertiesUtil {
          15    private static Properties properties = new Properties();
          16    private static FileInputStream fileInputStream;
          17
          18    /**
          19     * 從屬性文件中根據(jù)Key取值
          20     * @param key
          21     * @return
          22     */

          23    public static String getValueByKey(String key) {
          24        if (fileInputStream == null{
          25            try {
          26                fileInputStream = new FileInputStream("src/dpcp.properties");
          27            }
           catch (FileNotFoundException e) {
          28                e.printStackTrace();
          29            }

          30        }

          31        try {
          32            properties.load(fileInputStream);
          33        }
           catch (IOException e) {
          34            e.printStackTrace();
          35        }

          36        return properties.get(key).toString();
          37    }

          38}

          39

          4:測(cè)試客戶端
           1package net.vicp.jiasoft.dpcp.client;
           2
           3import java.sql.Connection;
           4import java.sql.SQLException;
           5import net.vicp.jiasoft.dpcp.connectionpool.ConnectionPool;
           6
           7/** 
           8 * @author Jak.Shen
           9 * 日期:2008-3-31
          10 * 說(shuō)明:動(dòng)態(tài)代理連接池測(cè)試客戶端
          11 */

          12public class DbPoolClient {
          13
          14    public static void main(String[] args) {
          15        ConnectionPool connectionPool = ConnectionPool.newInstance();
          16        Connection connection = connectionPool.getConnection();
          17        try {
          18            connection.close();
          19        }
           catch (SQLException e) {
          20            e.printStackTrace();
          21        }

          22    }

          23}

          24

          5:屬性配置文件(dpcp.properties)
           1#最大連接數(shù)
           2poolMaxSize=4
           3#連接用戶名
           4userName=scott
           5#連接密碼
           6password=tiger
           7#連接驅(qū)動(dòng)
           8driverClass=oracle.jdbc.driver.OracleDriver
           9#連接字符串
          10url=jdbc:oracle:thin:@localhost:1521:ACCP

          源碼下載 -- (ConnectionPool.rar)

          杰森 
          郵箱:json.shen(at)gmail.com
          網(wǎng)站:www.shenjia.org
          posted on 2008-03-31 18:17 杰森 閱讀(2442) 評(píng)論(2)  編輯  收藏 所屬分類: JavaSE

          評(píng)論:
          # re: Java實(shí)現(xiàn)簡(jiǎn)單動(dòng)態(tài)代理連接池 2008-04-18 10:33 | YangYang
          寫的很好,學(xué)習(xí)了。 msn:seeblue1981@hotmail.com  回復(fù)  更多評(píng)論
            
          # re: Java實(shí)現(xiàn)簡(jiǎn)單動(dòng)態(tài)代理連接池 2008-04-18 16:53 | Jak.Shen
          @YangYang
          多謝支持!  回復(fù)  更多評(píng)論
            
          嗨117
          主站蜘蛛池模板: 樟树市| 辉县市| 庄浪县| 德保县| 翁牛特旗| 株洲县| 咸丰县| 北碚区| 阳朔县| 湘潭市| 左权县| 青铜峡市| 镇宁| 德钦县| 兴文县| 崇仁县| 凤翔县| 禹城市| 姜堰市| 白玉县| 庆元县| 思茅市| 嘉义市| 芜湖市| 仙游县| 长宁县| 泸水县| 博客| 调兵山市| 南安市| 高安市| 新余市| 盘山县| 镇江市| 泽州县| 清苑县| 龙陵县| 广汉市| 延吉市| 满洲里市| 五原县|