动态代理在JDBC的DataSource中的应用

来源:互联网 发布:网络制式英文 编辑:程序博客网 时间:2024/06/08 06:08

目的:为数据连接池中的每一个Connection创建一个代理,当需要使用Connection对象操作数据库时,先判断是否超过连接池的最大连接数,如果没有超过,取得连接,否则不进行连接。

1、抽象对象角色
JDBC提供了Connection接口

2、定义我们自己的数据连接池,实现DataSource接口

public class MyDataSource implements DataSource{    private static String url = "jdbc:mysql://localhost:3306/jdbc";    private static String user = "root";    private static String password = "";    private static int initCount = 1;    private static int maxCount = 1;    int currentCount = 0;    LinkedList<Connection> connectionsPool = new LinkedList<Connection>();    public MyDataSource() {        try {            for (int i = 0; i < initCount; i++) {                this.connectionsPool.addLast(this.createConnection());                this.currentCount++;            }        } catch (SQLException e) {            throw new ExceptionInInitializerError(e);        }    }    public Connection getConnection() throws SQLException {        synchronized (connectionsPool) {            if (this.connectionsPool.size() > 0)                return this.connectionsPool.removeFirst();            if (this.currentCount < maxCount) {                this.currentCount++;                return this.createConnection();            }            throw new SQLException("服务器连接异常");        }    }    public void free(Connection conn) {        this.connectionsPool.addLast(conn);    }    private Connection createConnection() throws SQLException {        Connection realConn = DriverManager.getConnection(url, user, password); //真实对象        MyConnectionHandler proxy = new MyConnectionHandler(this); //代理处理器        return proxy.bind(realConn);    //创建代理对象    }    public Connection getConnection(String username, String password)            throws SQLException {        return null;    }    public PrintWriter getLogWriter() throws SQLException {        return null;    }    public int getLoginTimeout() throws SQLException {        return 0;    }    public void setLogWriter(PrintWriter out) throws SQLException {    }    public void setLoginTimeout(int seconds) throws SQLException {    }    @Override    public Logger getParentLogger() throws SQLFeatureNotSupportedException {        return null;    }    @Override    public <T> T unwrap(Class<T> iface) throws SQLException {        return null;    }    @Override    public boolean isWrapperFor(Class<?> iface) throws SQLException {        return false;    }}

3、定义动态代理处理类,实现InvocationHandler接口

class MyConnectionHandler implements InvocationHandler {    private Connection realConnection;    private Connection warpedConnection;    private MyDataSource dataSource;    private int maxUseCount = 5;    private int currentUserCount = 0;    MyConnectionHandler(MyDataSource2 dataSource) {        this.dataSource = dataSource;    }    //注意:不一定非要在该类中创建代理,只要在创建代理的时候传入一个MyConnectionHandler类的实例就可以了    Connection bind(Connection realConn) {        this.realConnection = realConn;        this.warpedConnection = (Connection) Proxy.newProxyInstance(this.realConnection .getClass().getClassLoader(), new Class[] { Connection.class },this);   //创建代理对象        return warpedConnection;    }    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        if (!"close".equals(method.getName())) {//非关闭连接操作            this.currentUserCount++;            if (this.currentUserCount <= this.maxUseCount)  //只有在这个类中进行判断后才进行连接,减轻了服务器的压力                return method.invoke(this.realConnection, args);        }else {            this.realConnection.close();            this.dataSource.currentCount--;        }        return null;    }}
0 0
原创粉丝点击