原文转自:http://www.uusam.com/uu/blog/article.asp?id=80 
		
		 
		最近研究Spring的JDBC DataSource配置问题,看到proxool这个东西,根据网上大部分网友的评论,对proxool情有独钟。我于是去下载了一个最新版本:
0.9.0RC2,你可以到http://proxool.sf.net/去下载。 
		我根据官方文档进行了Datasource的配置,但是发现了问题。像大多数网友反应的一样,出现了“参数无效的问题”。我根据源码进行了分析,终于发现了问题所在。
		 
		Proxool 指南里配置的例子如下:
		 
		
		
		
				
						
								| 
										 
												
														
																5. Configuration example for Tomcat
														
												
										 
										
										
												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 默认连接的数据源
										 
										
												    
												作者:悠游
										 
										
												    
												时间:2006-08-07
										 
										
												    
												备注:
										 
										
												         
												该类的诸多属性请参考Proxool文档.
										 
										
												    
										 
										
												-->
										 
										  
										
												<
												beans
												>
										 
										
												    
												<!-- Proxool 
												默认连接的数据源 -->
										 
										
												    
												<
												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
												>
										 
										  
								 | 
						
				
		
		 
		测试,结果和预期一样,参数无效报错了。断点跟踪到最后发现这么一个问题:配置的用户名和密码丢失!
		 
		大家都知道以前自己在写连接池的时候最后一步是这个DriverManager.getConnection(url, info)方法。 url就是连接的url,info是属性类。里面最基本要存放两个属性,不用说就知道是user和password。但是断点跟踪到proxool最后一步的时候发现info是空的,所以就出现了上述参数无效的问题。
		 
		
				       回头看问题到底出现在哪里?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
														>
												
										 
								 | 
						
				
		
		 
		
				       测试,结果通过,不过有点投机取巧。因为foo=1,bar=true和user=××,password=××都正好是两个属性。
		 
		
				    
				知道怎么回事了就行了,看来这是个BUG。经过解析,发现了最终原因:
		
		 
		
				类:
				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设置完成用户名和密码后,最后一步设置delegateProperties属性的时候把原来的属性给覆盖掉了,这个就是最终原因。改改:
		
		 
		
		
		
				
						
								| 
										 
												
														            
														cpd.setDelegateProperties(delegateProperties);
												
										 
										
												
														            
														cpd.setUser(getUser());
												
										 
										
												
														            
														cpd.setPassword(getPassword());
												
										 
								 | 
						
				
		
		
				    
		
		
				重新bunid、测试、ok!
		
		 
		
				
						Evil Gard 
				
				在
				2003
				年推出了
				0.8
				×版本,这次的
				0.9
				RC2
				改动较大。所以出现上述问题在所难免,偶英文不好。谁有时间去提交个
				BUG
				说明,希望早日看到
				0.9
				正式版推出。