首页 > 学院 > 开发设计 > 正文

java学习笔记—JDBC6(23)

2019-11-14 23:37:09
字体:
来源:转载
供稿:网友
java学习笔记—JDBC6(23)

1 用动态代理书写连接池

设计:

代理的目标:原生的connection。

   代理的目的:修改close方法,让close方法不可以关闭连接,且主动收回连接。

通过动态代理,和线程通讯:

1:对Cxonnection进行代理。

 2:在获取Connection时,通过同步,如果没有连接时,就让线程进入等待池。

 3:修改close方法,且在还了连接以后唤醒正在等待的线程。

package cn.itcast.utils;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.PRoxy;import java.sql.Connection;import java.sql.DriverManager;import java.util.ArrayList;import java.util.List;public class ConnUtils3 {    //第一步:声明连接池维护所有的连接    private static List<Connection> pool = new ArrayList<Connection>();     //第二步:静态代码块中创建多个连接    static{        try{            Class.forName("com.MySQL.jdbc.Driver");            String url = "jdbc:mysql:///db909?characterEncoding=UTF8";            for(int i=0;i<3;i++){                 final Connection con = DriverManager.getConnection(url,"root","1234");//com.mysql.jdbc.Jdbc4Connection@                //对con对象进行动态代理                Object proxyedCon =                          Proxy.newProxyInstance(                                ConnUtils3.class.getClassLoader(),                                new Class[]{Connection.class},                                //声明执行句柄,只对close方法设置拦截                                new InvocationHandler() {                                    public Object invoke(Object proxy, Method method, Object[] args)                                            throws Throwable {                                        if(method.getName().equals("close")){                                             System.err.println("有人想关闭连接,不能关,还连接");                                            //将proxy再加到pool中,这个proxy就是proxyedCon                                            synchronized (pool) {                                                pool.add((Connection) proxy);                                                 pool.notify();                                            }                                            return null;                                        }else{                                            System.err.println("放行"+method.getName());                                            return method.invoke(con, args);                                         }                                    }                                });                //一定要将代理对象添加到池中去。                pool.add((Connection) proxyedCon);             }        }catch(Exception e){            throw new RuntimeException(e.getMessage(),e);        }    }    /**     * 提供一个静态工厂方法返回一个连接     */    public static Connection getCon(){        synchronized (pool) {            if(pool.size()==0){                try {                    pool.wait();                } catch (InterruptedException e) {                    e.printStackTrace();                }                return getCon();            }            Connection con = pool.remove(0);//返回一个代理的connection对象            System.err.println("还有几个:"+pool.size());            return con;        }    }}

优化代码

通过类加载器读取一个资源文件:

SomeClass.class.getReesource(xxx) – 获取与SomeCalss字节码同一个目录下的xxx文件。

SomeClass.class.getClassLoader().getResource(“xxxx”); - 获取classpath根下上的xxx文件。

1:将url,driver,name,pwd写到一个配置文件中去。-properties

2:通过LinkedList来维护一个池。

读取资源文件,获取信息

//声明资源器类 -             Properties prop = new Properties();            //获取这个文件的路径            URL url = ConnUtils3.class.getClassLoader().getResource("jdbc.properties");            String path = url.getPath();            //为了防止有中文或是空格            path = URLDecoder.decode(path,"UTf-8");            File file = new File(path);            //加载jdbc.properties这个文件            prop.load(new FileInputStream(file));            //获取信息            String driver = prop.getProperty("driver");            Class.forName(driver);            String jdbcurl = prop.getProperty("url");            String nm = prop.getProperty("name");            String pwd = prop.getProperty("pwd");            //创建三个原生的连接,都将它们代理            String poolSize = prop.getProperty("poolSize");            int size = Integer.parseInt(poolSize);            for(int i=0;i<size;i++){                //创建多个连接,代理每一个连接。拦截close方法,还连接。
连接池的作用

1:维护多个连接。

在初始化时创建List,将多个连接放到List中去.

2:可以在close时回收连接

对Connection进行动态代理,

对close方法进行拦截。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表