JDBC数据源DBCP源代码情景分析

在之前的一篇博文从JDBC到commons-dbutils中,我曾经写到,对于获取数据库连接,有一个解决方案,那就是数据源。业界用到的比较普遍的开源数据源解决方案有很多,DBCP是其中一种,今天,我试图从源代码角度去解读这个解决方案。

全文分为三节,第一节介绍DBCP一般的用法,第二节按照第一节中给出的用法,从源代码角度看看,到底程序经过了哪些步骤,第三小节对全文做一个总结。

1、DBCP的一般用法 整理发布

DBCP的用法其实很简单,一般就是new一个BasicDataSource,然后设置参数,当需要获取连接的时候,就调用getConnection()方法。代码如下:

initDS(String connectURI, String username, String pswd, String driverClass, int initialSize,int maxActive, int maxIdle, int maxWait) {BasicDataSource ds = new BasicDataSource();ds.setDriverClassName(driverClass);ds.setUsername(username);ds.setPassword(pswd);ds.setUrl(connectURI);ds.setInitialSize(initialSize); ds.setMaxActive(maxActive);ds.setMaxIdle(maxIdle);ds.setMaxWait(maxWait);DS = ds;} //………………….//2 获取连接DS.getConnection();

其中driverClass是数据库驱动的类名,username是数据库用户名,pswd是数据库密码,connectURI是连接数据库的URI,initiialSize是初始化的时候创建的连接数

maxActive是允许活动的最大连接数,maxIdle是最大闲置连接数,maxWait是获取一个连接时最大的等待时间(毫秒)

2、对上述情景的源代码分析

在构造BasicDataSource以及为它设置参数的时候(上述第一步),其实BasicDataSource并没有构造完成,只有当第一次调用getConnection方法的时候,才会去构造真正的数据源,具体可以从代码看出:

/*** Create (if necessary) and return a connection to the database.** @throws SQLException if a database access error occurs* @return a database connection*/public Connection getConnection() throws SQLException {return createDataSource().getConnection();}

从源代码可以看出,获取连接之前先要创建数据源,创建的数据源将作为BasicDataSource内部的数据源,为获取连接提供服务。下面对这个createDataSource()方法进行解释,先看它的源代码:

/*** <p>Create (if necessary) and return the internal data source we are* using to manage our connections.</p>** <p><strong>IMPLEMENTATION NOTE</strong> – It is tempting to use the* "double checked locking" idiom in an attempt to avoid synchronizing* on every single call to this method. However, this idiom fails to* work correctly in the face of some optimizations that are legal for* a JVM to perform.</p>** @throws SQLException if the object pool cannot be created. DataSource createDataSource()throws SQLException {if (closed) {throw new SQLException("Data source is closed");}(dataSource != null) {return (dataSource);}// create factory which returns raw physical connectionsConnectionFactory driverConnectionFactory = createConnectionFactory();// create a pool for our connectionscreateConnectionPool();// Set up statement pool, if desiredGenericKeyedObjectPoolFactory statementPoolFactory = null;if (isPoolPreparedStatements()) {statementPoolFactory = new GenericKeyedObjectPoolFactory(null,-1, // unlimited maxActive (per key)GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL,0, // maxWait1, // maxIdle (per key)maxOpenPreparedStatements);}// Set up the poolable connection factorycreatePoolableConnectionFactory(driverConnectionFactory, statementPoolFactory, abandonedConfig);// Create and return the pooling data source to manage the connectionscreateDataSourceInstance();try {for (int i = 0 ; i < initialSize ; i++) {connectionPool.addObject();}} catch (Exception e) {throw new SQLNestedException("Error preloading the connection pool", e);}return dataSource;}

从源代码可以看出,createDataSource()方法通过7步,逐步构造出一个数据源,下面是详细的步骤:

1、检查数据源是否关闭或者是否创建完成,如果关闭了就抛异常,如果已经创建完成就直接返回。

2、调用createConnectionFactory()创建JDBC连接工厂driverConnectionFactory,这个工厂使用数据库驱动来创建最底层的JDBC连接

3、调用createConnectionPool()创建数据源使用的连接池,连接池顾名思义就是缓存JDBC连接的地方。

4、如果需要就设置statement的缓存池,这个一般不需要设置

还深深埋在心底,要除去,怕是不能活命。

JDBC数据源DBCP源代码情景分析

相关文章:

你感兴趣的文章:

标签云: