`

读数据库连接池DBCP 源码

    博客分类:
  • java
阅读更多
在阅读DBCP源码前得先阅读commons-pool的原源码。
下面是几个主要的类的关系图。


1、BasicDataSource是我们最常见的类,配置数据源的时候就是写的这个。
它里面有一个getConnection方法,每次调用时就是从连接池中获取Connection。
具体的实现方法是在PoolingDataSource.java中,源码中如下:
 public Connection getConnection() throws SQLException {
        try {
            Connection conn = (Connection)(_pool.borrowObject());
            if (conn != null) {
                conn = new PoolGuardConnectionWrapper(conn);
            } 
            return conn;
        } catch(SQLException e) {
            throw e;
        } catch(NoSuchElementException e) {
            throw new SQLNestedException("Cannot get a connection, pool error " + e.getMessage(), e);
        } catch(RuntimeException e) {
            throw e;
        } catch(Exception e) {
            throw new SQLNestedException("Cannot get a connection, general error", e);
        }
    }

里面的_pool.borrowObject();就是从池中获取对象。
2、接着看PoolableConnectionFactory.java 这个就是commons-pool需要我们实现的创建池化对象的工厂类。
 public Object makeObject() throws Exception {
        Connection conn = _connFactory.createConnection();
        if (conn == null) {
            throw new IllegalStateException("Connection factory returned null from createConnection");
        }
        initializeConnection(conn);
        if(null != _stmtPoolFactory) {
            KeyedObjectPool stmtpool = _stmtPoolFactory.createPool();
            conn = new PoolingConnection(conn,stmtpool);
            stmtpool.setFactory((PoolingConnection)conn);
        }
        return new PoolableConnection(conn,_pool,_config);
    }

这段代码就是调用ConnectionFactory创建连接对象的方法,并且返回的是封装好的PoolableConnection类。
3、最后看PoolingConnection.java 中的close方法。
public synchronized void close() throws SQLException {
        if (_closed) {
            return;
        }

        boolean isUnderlyingConectionClosed;
        try {
            isUnderlyingConectionClosed = _conn.isClosed();
        } catch (SQLException e) {
            try {
                _pool.invalidateObject(this); 
            } catch(IllegalStateException ise) {
                passivate();
                getInnermostDelegate().close();
            } catch (Exception ie) {
               
            }
            throw (SQLException) new SQLException("Cannot close connection (isClosed check failed)").initCause(e);
        }

        if (!isUnderlyingConectionClosed) {
          
            try {
                _pool.returnObject(this); 
            } catch(IllegalStateException e) {
                passivate();
                getInnermostDelegate().close();
            } catch(SQLException e) {
                throw e;
            } catch(RuntimeException e) {
                throw e;
            } catch(Exception e) {
                throw (SQLException) new SQLException("Cannot close connection (return to pool failed)").initCause(e);
            }
        } else {
            
            try {
                _pool.invalidateObject(this); // XXX should be guarded to happen at most once
            } catch(IllegalStateException e) {
                // pool is closed, so close the connection
                passivate();
                getInnermostDelegate().close();
            } catch (Exception ie) {
            }
            throw new SQLException("Already closed.");
        }
    }

最后这个close方法里面是把对象给return到pool中。

看到这里,在使用DBCP时还是得调用close方法一下,把连接还给pool。

  • 大小: 65.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics