[英]How to extend c3p0 ComboPooledDataSource
Ok I have a resource in Tomcat 5.5 in server.xml for database connection like this: 好的,我在server.xml中的Tomcat 5.5中有一个资源用于数据库连接,如下所示:
<Resource name="jdbc/MyApp" auth="Container" type="com.mchange.v2.c3p0.ComboPooledDataSource" driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver" maxPoolSize="100" minPoolSize="5"
acquireIncrement="5"
user="username"
password="password"
factory="org.apache.naming.factory.BeanFactory"
jdbcUrl="jdbc:sqlserver://localhost:1433;databaseName=myDatabase;autoReconnect=true" />
Has anyone tried to extend the above ComboPooledDataSource? 有没有人试图扩展上面的ComboPooledDataSource? Problem is that database password is in clear text.
问题是数据库密码是明文。 Idea is to first encrypt the password and place the encrypted key in the server.xml.
想法是首先加密密码并将加密密钥放在server.xml中。 I have a decrypting utility so I can decrypt the key before trying to connect to database.
我有一个解密实用程序,所以我可以在尝试连接数据库之前解密密钥。
I found an example solution for my problem for org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory, but I'm not using this connection pool. 我为org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory的问题找到了一个示例解决方案,但我没有使用此连接池。 I'm using C3P0.
我正在使用C3P0。 Anyone tried this before with C3P0?
有没有人用C3P0尝过这个?
Yes, you can't extend com.mchange.v2.c3p0.ComboPooledDataSource
because it is public. 是的,您无法扩展
com.mchange.v2.c3p0.ComboPooledDataSource
因为它是公共的。 Here is the workaround by which I have achieved this. 这是我实现这一目标的解决方法。
I have extended org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
and passed the com.mchange.v2.c3p0.ComboPooledDataSource
datasource as a constructor argument. 我扩展了
org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
,并将com.mchange.v2.c3p0.ComboPooledDataSource
数据源作为构造函数参数传递。
Here is my hibernate.cfg.xml
configuration of above datasource: 这是我上面数据源的
hibernate.cfg.xml
配置:
<bean id="dataSource" class="MyDataSource">
<constructor-arg ref="c3p0DataSource" />
</bean>
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driver.className}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="acquireIncrement" value="${dataSource.acquireIncrement}" />
<property name="acquireRetryAttempts" value="${dataSource.acquireRetryAttempts}" />
<property name="acquireRetryDelay" value="${dataSource.acquireRetryDelay}" />
<property name="autoCommitOnClose" value="${dataSource.autoCommitOnClose}" />
<property name="breakAfterAcquireFailure" value="${dataSource.breakAfterAcquireFailure}" />
<property name="checkoutTimeout" value="${dataSource.checkoutTimeout}" />
<property name="debugUnreturnedConnectionStackTraces"
value="${dataSource.debugUnreturnedConnectionStackTraces}" />
<property name="forceIgnoreUnresolvedTransactions"
value="${dataSource.forceIgnoreUnresolvedTransactions}" />
<property name="idleConnectionTestPeriod" value="${dataSource.idleConnectionTestPeriod}" />
<property name="initialPoolSize" value="${dataSource.initialPoolSize}" />
<property name="maxAdministrativeTaskTime" value="${dataSource.maxAdministrativeTaskTime}" />
<property name="maxConnectionAge" value="${dataSource.maxConnectionAge}" />
<property name="maxIdleTime" value="${dataSource.maxIdleTime}" />
<property name="maxIdleTimeExcessConnections" value="${dataSource.maxIdleTimeExcessConnections}" />
<property name="maxPoolSize" value="${dataSource.maxPoolSize}" />
<property name="maxStatements" value="${dataSource.maxStatements}" />
<property name="maxStatementsPerConnection" value="${dataSource.maxStatementsPerConnection}" />
<property name="minPoolSize" value="${dataSource.minPoolSize}" />
<property name="numHelperThreads" value="${dataSource.numHelperThreads}" />
<property name="propertyCycle" value="${dataSource.propertyCycle}" />
<property name="testConnectionOnCheckin" value="${dataSource.testConnectionOnCheckin}" />
<property name="testConnectionOnCheckout" value="${dataSource.testConnectionOnCheckout}" />
<property name="unreturnedConnectionTimeout" value="${dataSource.unreturnedConnectionTimeout}" />
</bean>
Mine jdbc.properties file:
jdbc.driver.className=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=xxxxx
jdbc.username=xxx
jdbc.password=xxxxxxxxx #Encrytped password here
jdbc.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=update
dataSource.acquireIncrement=3
dataSource.acquireRetryAttempts=30
dataSource.acquireRetryDelay=60000
dataSource.autoCommitOnClose=false
dataSource.breakAfterAcquireFailure=false
dataSource.checkoutTimeout=0
dataSource.debugUnreturnedConnectionStackTraces=false
dataSource.forceIgnoreUnresolvedTransactions=false
dataSource.idleConnectionTestPeriod=0
dataSource.initialPoolSize=10
dataSource.maxAdministrativeTaskTime=0
dataSource.maxConnectionAge=0
dataSource.maxIdleTime=0
dataSource.maxIdleTimeExcessConnections=0
dataSource.maxPoolSize=10
dataSource.maxStatements=0
dataSource.maxStatementsPerConnection=0
dataSource.minPoolSize=10
dataSource.numHelperThreads=3
dataSource.propertyCycle=0
dataSource.testConnectionOnCheckin=false
dataSource.testConnectionOnCheckout=false
dataSource.unreturnedConnectionTimeout=0
Mine extended class where I decrypt the password before passing the datasource to transaction Proxy wrapper.
import javax.sql.DataSource;
import org.jasypt.util.text.BasicTextEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import com.csc.emms.common.EMMSConstraints;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class MyDataSource extends TransactionAwareDataSourceProxy
{
private static char[] appName =
{
'B', 'I', 'N', 'G', 'O', 'D', 'I', 'N', 'G', 'O'
};
@Autowired
// Inject your class by constructor
MyDataSource(ComboPooledDataSource dataSource)
{
super.setTargetDataSource(decryptPassword(dataSource));
}
private DataSource decryptPassword(ComboPooledDataSource dataSource)
{
dataSource.setPassword(decode(dataSource.getPassword()));
return dataSource;
}
private String decode(String encodedPassword)
{
BasicTextEncryptor decoder = new BasicTextEncryptor();
decoder.setPasswordCharArray(appName);
return decoder.decrypt(encodedPassword);
}
private String encode(String password)
{
BasicTextEncryptor encoder = new BasicTextEncryptor();
encoder.setPasswordCharArray(appName);
return encoder.encrypt(password);
}
}
Hope this resolved your issue.
由于com.mchange.v2.c3p0.ComboPooledDataSource
是公共最终类,因此无法扩展它。
You can't extend ComboPooledDataSource
, but you can basically duplicate it by extending its parent class, AbstractComboPooledDataSource
. 您无法扩展
ComboPooledDataSource
,但您可以通过扩展其父类AbstractComboPooledDataSource
来基本复制它。 You can really, really get close to duplicating it by either getting the source from Github , or by decompiling the class file. 通过从Github获取源代码 ,或者通过反编译类文件,你真的可以真正地接近复制它。 The result will look something like this:
结果将如下所示:
import com.mchange.v2.c3p0.AbstractComboPooledDataSource;
public final class YourC3p0DataSource extends AbstractComboPooledDataSource
implements Serializable, Referenceable {
public void setPassword(String encryptedPassword) {
try {
String decryptedPassword
= yourDecryption(encryptedPassword);
super.setPassword(decryptedPassword);
} catch (Exception e) { /* ... */ }
}
/* Increment a few other methods found in ComboPooledDataSource. */
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.