原文轉(zhuǎn)自:http://www.uusam.com/uu/blog/article.asp?id=80
?
最近研究Spring的JDBC DataSource配置問題,看到proxool這個東西,根據(jù)網(wǎng)上大部分網(wǎng)友的評論,對proxool情有獨鐘。我于是去下載了一個最新版本:0.9.0RC2,你可以到http://proxool.sf.net/去下載。
我根據(jù)官方文檔進行了Datasource的配置,但是發(fā)現(xiàn)了問題。像大多數(shù)網(wǎng)友反應(yīng)的一樣,出現(xiàn)了“參數(shù)無效的問題”。我根據(jù)源碼進行了分析,終于發(fā)現(xiàn)了問題所在。
?
Proxool 指南里配置的例子如下:
?
5. Configuration example for Tomcat
Configuration method: ObjectFactory
Configure a resource with ProxoolDataSource as the factory in server.xml (or the other places a context element can exist):
<context>
??? <Resource
??????? name="jdbc/mydatasource"
??????? auth="Container"
??????? type="javax.sql.DataSource"
??????? factory="org.logicalcobwebs.proxool.ProxoolDataSource"
??????? proxool.alias="hrs"
??????? user="joe"
??????? password="******"
??????? delegateProperties="foo=bar"
??????? proxool.driver-url="jdbc:oracle:thin:@127.0.0.1:1521:DB"
??????? proxool.driver-class="oracle.jdbc.driver.OracleDriver"/>
</context> |
?
看完后照著例子做,寫出簡單的配置文件:
?
<?
xml
version
=
"1.0"
encoding
=
"GBK"
?>
<!
DOCTYPE
beans
PUBLIC
"-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd"
>
<!--
???
描述: ProxoolSample 默認連接的數(shù)據(jù)源
???
作者:悠游
???
時間:2006-08-07
???
備注:
??? ????
該類的諸多屬性請參考Proxool文檔.
???
-->
?
<
beans
>
???
<!-- Proxool
默認連接的數(shù)據(jù)源 -->
???
<
bean
id
=
"ProxoolSample"
???????
class
=
"org.logicalcobwebs.proxool.ProxoolDataSource"
>
???????
<
property
name
=
"driver"
>
???????????
<
value
>
${oracle.121.driverClassName}
</
value
>
???????
</
property
>
???????
<
property
name
=
"driverUrl"
>
???????????
<
value
>
${oracle.121.url}
</
value
>
???????
</
property
>
???????
<
property
name
=
"user"
>
???????????
<
value
>
${oracle.121.userName}
</
value
>
???????
</
property
>
???????
<
property
name
=
"password"
>
???????????
<
value
>
${oracle.121.passWord}
</
value
>
???????
</
property
>
???
</
bean
>
???
???
<!--
配置屬性文件 -->
???
<
import
resource
=
"../resource/Properties.xml"
/>
</
beans
>
?
|
?
測試,結(jié)果和預(yù)期一樣,參數(shù)無效報錯了。斷點跟蹤到最后發(fā)現(xiàn)這么一個問題:配置的用戶名和密碼丟失!
?
大家都知道以前自己在寫連接池的時候最后一步是這個DriverManager.getConnection(url, info)方法。 url就是連接的url,info是屬性類。里面最基本要存放兩個屬性,不用說就知道是user和password。但是斷點跟蹤到proxool最后一步的時候發(fā)現(xiàn)info是空的,所以就出現(xiàn)了上述參數(shù)無效的問題。
?
?????? 回頭看問題到底出現(xiàn)在哪里?info不就是一開始的時候注入到工廠里面的delegateProperties屬性么?看他的源碼如下:
???
/**
????
*
Set
any
property
that
should
be
handed
to
the
delegate
driver.
????
*
E.g.
<code>foo=1,bar=true</code>
????
*
@param
properties
a
comma
delimited
list
of
name=value
pairs
????
*
@see
ConnectionPoolDefinitionIF#getDelegateProperties()
????
*/
???
public
void
setDelegateProperties(String
properties)
{
???????
StringTokenizer
stOuter
=
new
StringTokenizer(properties,
","
);
???????
while
(stOuter.hasMoreTokens())
{
???????????
StringTokenizer
stInner
=
new
StringTokenizer(stOuter.nextToken(),
"="
);
???????????
if
(stInner.countTokens()
!=
2)
{
???????????????
throw
new
IllegalArgumentException(
"Unexpected delegateProperties value: '"
+
properties
+
"'. Expected 'name=value'"
);
???????????
}
???????????
delegateProperties.put(stInner.nextToken().trim(),
stInner.nextToken().trim());
???????
}
???
}
|
?????? 不用細看,大概就知道他希望如果有的話把foo=1,bar=true兩個附加屬性放進去了。那個用戶名和密碼怎么沒放進去呢?自己放算了,于是我這樣增加了點東西:
?
???
<
property
name
=
"delegateProperties"
>
?????
<
value
>
user=${oracle.121.userName},password=${oracle.121.passWord}
</
value
>
???
</
property
>
|
?
?????? 測試,結(jié)果通過,不過有點投機取巧。因為foo=1,bar=true和user=××,password=××都正好是兩個屬性。
?
???
知道怎么回事了就行了,看來這是個BUG。經(jīng)過解析,發(fā)現(xiàn)了最終原因:
?
類:
ProxoolDataSource
方法:registerPool
問題:
???
???????????
cpd.setAlias(getAlias());
????? ??????
cpd.setDriver(getDriver());
???????????
cpd.setFatalSqlExceptionsAsString(getFatalSqlExceptionsAsString());
???????????
cpd.setFatalSqlExceptionWrapper(getFatalSqlExceptionWrapperClass());
???????????
cpd.setHouseKeepingSleepTime(getHouseKeepingSleepTime());
???????????
cpd.setHouseKeepingTestSql(getHouseKeepingTestSql());
???????????
cpd.setMaximumActiveTime(getMaximumActiveTime());
???????????
cpd.setMaximumConnectionCount(getMaximumConnectionCount());
???????????
cpd.setMaximumConnectionLifetime(getMaximumConnectionLifetime());
???????????
cpd.setMinimumConnectionCount(getMinimumConnectionCount());
???????????
cpd.setPrototypeCount(getPrototypeCount());
???????????
cpd.setPassword(getPassword());
???????????
cpd.setRecentlyStartedThreshold(getRecentlyStartedThreshold());
???????????
cpd.setSimultaneousBuildThrottle(getSimultaneousBuildThrottle());
???????????
cpd.setUser(getUser());
???????????
cpd.setStatistics(getStatistics());
???????????
cpd.setStatisticsLogLevel(
getStatisticsLogLevel
());
?????? ?????
cpd.setTrace(isTrace());
???????????
cpd.setUrl(getDriverUrl());
???????????
cpd.setVerbose(isVerbose());
???????????
cpd.setJmx(isJmx());
???????????
cpd.setJmxAgentId(getJmxAgentId());
???????????
cpd.setTestAfterUse(isTestAfterUse());
???????????
cpd.setTestBeforeUse(isTestBeforeUse());
???????????
cpd.setDelegateProperties(delegateProperties);
|
???
cpd
對象里面有個properties屬性。在cpd設(shè)置完成用戶名和密碼后,最后一步設(shè)置delegateProperties屬性的時候把原來的屬性給覆蓋掉了,這個就是最終原因。改改:
?
???????????
cpd.setDelegateProperties(delegateProperties);
???????????
cpd.setUser(getUser());
?????? ?????
cpd.setPassword(getPassword());
|
???
重新bunid、測試、ok!
?
Evil Gard
在
2003
年推出了
0.8
×版本,這次的
0.9
RC2
改動較大。所以出現(xiàn)上述問題在所難免,偶英文不好。誰有時間去提交個
BUG
說明,希望早日看到
0.9
正式版推出。