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

目的:为数据连接池中的每一个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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值