JDBC-连接池之装饰者和动态代理

来源:互联网 发布:java微信企业号开发 编辑:程序博客网 时间:2024/06/04 01:05

    • 前言
    • 通过装饰者模式来定义连接池
      • 定义Connection实现
      • 定义DataSource实现的实现
    • 通过动态代理来定义连接池
      • 定义Connection实现
      • 动态代理动态的去选择执行对象
    • 总结

前言

JDBC连接池的存在,解决了数据库连接和释放资源的性能问题,通过在程序初始化的时候创建一定数量的连接,通过集合保存,每当需要进行数据库操作的时候,在连接池中拿,使用完毕后,不是释放资源而是在将拿出的连接对象放入集合中,这样就提高了性能。

通过装饰者模式来定义连接池

定义Connection实现

public class MyConnection implements Connection {    private Connection connection;    private LinkedList<Connection> linkedList;    public MyConnection(Connection connection, LinkedList<Connection> linkedList) {        this.connection = connection;        this.linkedList = linkedList;    }    @Override    public Statement createStatement() throws SQLException {        return connection.createStatement();    }    @Override    public void close() throws SQLException {        System.out.println("=========");        //将回收的Connection实例加进集合中        linkedList.addLast(connection);    }   ......   ......  }

定义DataSource实现的实现

/** * Created by yzz on 2017/8/27. * mail:yzzstyle@163.com */public class ConnectionPool_1 implements DataSource {    private static LinkedList<Connection> linkedList = new LinkedList<>();    static {    //类加载时创建一定数量的连接        initPool();    }    public static void initPool(){        for (int i = 0; i <5 ; i++) {            Connection connection = JDBCUtils.getConnection();            //将Connection对象进行装饰            MyConnection conn = new MyConnection(connection,linkedList);            //将装饰着的实例加入到集合中            linkedList.addFirst(conn);        }    }    @Override    public Connection getConnection() throws SQLException {        if (linkedList.size()==0){            initPool();        }        //访问一个连接,集合就要移除该连接        return linkedList.removeFirst();    }    public static void close(Connection connection){        if (connection==null)return;        try {        //调用的close方法是装饰过后的方法            connection.close();        } catch (SQLException e) {            e.printStackTrace();        }    }    ......    ......    }

通过动态代理来定义连接池

定义Connection实现

只需要实现close方法即可,只要当调用close方法时,才会去代理目标,其他方法代理不做任何事,还是交给目标Connection执行。

public class ConnectionProxy implements Connection{    private Connection connection;    private LinkedList<Connection> linkedList;    public ConnectionProxy(Connection connection, LinkedList<Connection> linkedList) {        this.connection = connection;        this.linkedList = linkedList;    }    @Override    public void close() throws SQLException {        System.out.println("=====================");        linkedList.addLast(connection);    }    ......    ......    }

动态代理,动态的去选择执行对象

/** * Created by yzz on 2017/8/27. * mail:yzzstyle@163.com * 1.传递一个目标对象和一个代理实现 * 2.当调用close方法时由代理对象执行,否则由目标对象执行 * 3.在invoke()的返回值就是方法调用的返回值,用户不能自己想当然,必须要严谨 */public class Connectionutils {    public static Connection  getConn(Connection connection,Connection proxyConn){        Connection c = null;        try {            c = (Connection) Proxy.newProxyInstance(                    connection.getClass().getClassLoader(),                    new Class[]{Connection.class},                    new InvocationHandler() {                        @Override                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                            System.out.println(proxy.getClass());                            if ("close".equals(method.getName())){                                return method.invoke(proxyConn,args);                            }else {                               return method.invoke(connection,args);                            }                        }                    }            );        }catch (Exception e){            e.printStackTrace();        }finally {            return c;        }    }}

总结

通过装饰者模式和动态代理都优化了连接池操作,但是相比之下,还是动态代理更好,只需要根据需要来实现相关的方法,不需要重写接口中所有的方法。通过反射来判断当下执行的方法,动态的去选择执行者。

原创粉丝点击