文章主要是通过commons-dbcp-1.4-src之中的相关源代码进行学习与分析。点击下载源代码文件。
由于本人还是一枚小莱鸟,内功修为还达不到‘九阴真经’的地步,所以一旦发现练功有走火入魔,还望各位‘高手师傅’给予指点。
BasicDataSourceFactory实现了javax.naming.spi.ObjectFactory接口。
因此,先从ObjectFactory学习。
一、ObjectFactory接口
该接口需要实现方法:
getObjectInstance(Object object,Name name,Context namCtx,HashTable,?> enviroment)
该方法线程安全,作用为使用本地或引用的特殊信息,创建一个对象。而此类对象的特殊性体现在于具体的环境(代码中的HashTable入参)。
参数解释:
Object:为所创对象提供相关的信息,可为空;
name:与参数namCtx相关的名字,可为空;
namCtx:与规定参数相关的上下文内容,可为空;
environment:被用来创造对象的环境,可为空。
其实对这个方法具体的一些作用与结构,还并不是特别理解,欢迎高手们一起指点;不知道getOjectInstance与java的反射机制有无关联?
二、BasicDataSourceFactory类
该类一共有3个比较主要的方法,分别为getOjectInstance、createDataSource以及getProperties三个方法。下面具体学习这三个方法。
1、public Object getOjectInstance(Ojbect object,Name name,Context namCtx,HashTable,?> enviroment)方法
该方法主要是实现ObjectFactory提供的抽象方法。其中Object入参必须是Reference类的一个实例,即必须为一个符合Java规范(命名)的Object,同时该参数也必须实现javax.sql.DataSource接口。
此外,该方法还将BasicDataFactory中的一些与数据源(即参数Object对象)相关的参数集合成一个Properties对象;具体的参数会在下文介绍。
获取数据源中的参数及参数值的具体实现过程如下:
Reference(javax.naming.Reference)类有点类似与C语言的指针;当Object被强制转换为一个Reference对象之后,会通过Reference的实例方法get(String propertyName)获取指定的属性值;而此处的属性值,并不是真正的属性值,而是属性值的一个引用值,即一个RefAddr对象,该对象就相当于C语言的指针;如要通过‘指针’获取‘指针指向的内容’时,只需调用RefAddr对象的getContent()方法即可。
如此就获取到指定属性的属性值了。
最后调用createDataSource(Properties properties)方法创建数据源。
2、public static DataSource createDataSource(Properties properties)方法
该方法主要有三个步骤,第一步是new一个新的BasicDataSource对象,第二步根据properties入参,设置该BasicDataSource的一些相关参数;第三步则是将设置好参数的BasicDataSource返回。
由于BasicDataSource的参数比较众多,因此可以将这些参数分成7个大类,具体情况如下表所示:
类型 |
参数名 |
描述 |
默认值 |
数据库连接 |
DirverClassName |
数据库驱动名称 |
|
userName |
用户名 |
|
|
password |
密码 |
|
|
url |
数据库地址(数据库名) |
|
|
connectionProperties |
连接参数(格式:key=value;) |
|
|
连接 事务 |
defaultAutoCommit |
某个连接默认自动提交 |
true |
defaultReadOnly |
默认只读模式 |
Driver default |
|
defaultTransactionIsolation |
默认事物隔离级别: NONE:不支持事务 READ_COMMITTED:当前事务更改时不锁表,其他事务读取数据,未提交,则读取更改前的,已提交,则读取已更改的。 READ_UNCOMMITEED:无论是否提交,都读取更改值。 REPEATABLE_READ:只能读取新增值,无法读取修改值。 SERIALIZABLE:查询时,不允许其他事务进行修改操作。 |
Driver default |
|
defaultCatalog |
默认目录 |
|
|
数据池连接 |
maxActive |
池最大连接数 |
8 |
maxIdle |
池最大空闲数 |
8 |
|
minIdle |
池最小空闲数 |
0 |
|
InitialiSize |
初始化连接数 |
0 |
|
maxWait |
获取连接最大等待时间 |
indefinitely |
|
测试有效性 |
testOnBorrow |
借连接时,是否检测连接的有效性 |
true |
testOnReturn |
还连接时,是否检测连接的有效性 |
false |
|
timeBetweenEvictimeRun |
每隔多少时间,对超过检测时间间隔的连接对象进行检测(大于0,反之不检测) |
-1 |
|
minEvictableIdleTimeMillis |
检测时间间隔(即对闲置时间超过该值的连接检测) |
30*60*1000 |
|
numTestsPerEvictionRum |
每次检测连接的数量 |
3 |
|
testWhileIdle |
获取空闲连接时,是否检测其有效性 |
false |
|
Sql 语句 |
poolPreparedStatement |
是否将预处理语句缓存至连接池之中 |
false |
maxOpenPerparedStatement |
语句最大预处理数 |
|
|
底层 连接 |
accessToUnderlyingConnectionAllowed |
是否允许访问底层的连接(即守护连接关闭的情况下,能否继续使用底层连接)慎重使用 |
false |
废弃 连接 |
removeAbandonedTimeout |
超时时间 |
300 |
removeAbandoned |
是否自动回收超时的废弃连接 |
false |
|
logAbandoned |
是否打印回收废弃连接时的日志 |
false |
每个参数的不同配置(不同的值)都将影响到BasicDataSource的允运行性能与效率。
3、getProperty(String propText)方法
将格式为key=value;...的字符串解析为Properties实例。在createDataSource方法之中,会调用此方法,将connectionProperties参数(String类型),转化为Properties实例。
三、总结
BasicDataSourceDataFactory主要根据一个实现了DataSource接口的对象,获取该对象的相关数据源配置参数(通过Reference对象,采用类似指针的方法),然后将new一个BaiscDataSource对象,结合获取的参数,形成一个BasicDataSource对象,并将之返回。