技术开发 频道

使用Java动态代理实现数据库连接池

  从使用者的示例代码就可以看出,我们已经解决了常规连接池产生的两个问题。但是我们最最关心的是如何解决接管close方法的办法。接管工作主要在ConnectionFactory中的两句代码:
source = new DataSourceImpl(param); source.initConnection();
  DataSourceImpl是一个实现了接口javax.sql.DataSource的类,该类维护着一个连接池的对象。由于该类是一个受保护的类,因此它暴露给使用者的方法只有接口DataSource中定义的方法,其他的所有方法对使用者来说都是不可视的。我们先来关心用户可访问的一个方法getConnection
/** * @see javax.sql.DataSource#getConnection(String,String) */ public Connection getConnection(String user, String password) throws SQLException { //首先从连接池中找出空闲的对象 Connection conn = getFreeConnection(0); if(conn == null){ //判断是否超过最大连接数,如果超过最大连接数 //则等待一定时间查看是否有空闲连接,否则抛出异常告诉用户无可用连接 if(getConnectionCount() >= connParam.getMaxConnection()) conn = getFreeConnection(connParam.getWaitTime()); else{//没有超过连接数,重新获取一个数据库的连接 connParam.setUser(user); connParam.setPassword(password); Connection conn2 = DriverManager.getConnection(connParam.getUrl(), user, password); //代理将要返回的连接对象 _Connection _conn = new _Connection(conn2,true); synchronized(conns){ conns.add(_conn); } conn = _conn.getConnection(); } } return conn; } /** * 从连接池中取一个空闲的连接 * @param nTimeout 如果该参数值为0则没有连接时只是返回一个null * 否则的话等待nTimeout毫秒看是否还有空闲连接,如果没有抛出异常 * @return Connection * @throws SQLException */ protected synchronized Connection getFreeConnection(long nTimeout) throws SQLException { Connection conn = null; Iterator iter = conns.iterator(); while(iter.hasNext()){ _Connection _conn = (_Connection)iter.next(); if(!_conn.isInUse()){ conn = _conn.getConnection(); _conn.setInUse(true); break; } } if(conn == null && nTimeout > 0){ //等待nTimeout毫秒以便看是否有空闲连接 try{ Thread.sleep(nTimeout); }catch(Exception e){} conn = getFreeConnection(0); if(conn == null) throw new SQLException("没有可用的数据库连接"); } return conn; }
  DataSourceImpl类中实现getConnection方法的跟正常的数据库连接池的逻辑是一致的,首先判断是否有空闲的连接,如果没有的话判断连接数是否已经超过最大连接数等等的一些逻辑。但是有一点不同的是通过DriverManager得到的数据库连接并不是及时返回的,而是通过一个叫_Connection的类中介一下,然后调用_Connection.getConnection返回的。如果我们没有通过一个中介也就是JAVA中的Proxy来接管要返回的接口对象,那么我们就没有办法截住Connection.close方法。
0
相关文章