1

我正在使用在 tomcat 服务器中配置的 JNDI 数据源。我想避免将密码存储为明文,而且我在使用的应用程序中有一个现有的加密逻辑,我想用它来加密数据库密码。

<Resource name="jdbc/testdb" auth="Container"
      factory="com.zaxxer.hikari.HikariJNDIFactory"
      type="javax.sql.DataSource"
      minimumIdle="5" 
      maximumPoolSize="50"
      connectionTimeout="300000"
      driverClassName="org.mariadb.jdbc.Driver"
      jdbcUrl="jdbc:mysql://localhost:3307/testdb"
      dataSource.implicitCachingEnabled="true" 
      connectionTestQuery="Select 1" />

考虑到这个用例和在线可用的可能解决方案,我决定使用 org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter 来使用代码为数据库提供用户名和密码

<bean id="dataSource1" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jdbc/testdb" />
    </bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter">
   <property name="targetDataSource" ref="dataSource1"/>
   <property name="username" value="${dataSource.username}"/>
   <property name="password" value="#{passwordDecryptor.decryptedString}"/>
 </bean>

这种方法适用于我与 MSSQL 数据库建立连接,但奇怪的是在 MariaDB 上失败,并出现错误“访问被拒绝用户''@'localhost'(使用密码:NO)”。我想知道这个问题是否与 HikariCP 连接池有关,因为同样适用于 C3P0 实现,没有任何问题。

另外我想知道这是否是正确的方法,请建议这是否可以改进以获得更好的性能。

4

1 回答 1

2

好的,我已经四处看看,试一试:

<Resource name="jdbc/testdb" auth="Container"
    factory="org.apache.naming.factory.BeanFactory"
    type="com.zaxxer.hikari.HikariDataSource"
    minimumIdle="5" 
    maximumPoolSize="50"
    connectionTimeout="300000"
    driverClassName="org.mariadb.jdbc.Driver"
    jdbcUrl="jdbc:mysql://localhost:3307/testdb"
    connectionTestQuery="Select 1" />

有什么不同吗?我们没有使用com.zaxxer.hikari.HikariJNDIFactory. 为什么?因为HikariJNDIFactory使用HikariDataSource(HikariConfig config)构造函数,它立即实例化底层数据源,之后就不能再更改配置。

使用BeanFactory,我们调用默认构造函数,它在第一次调用 之前不会实例化底层数据源getConnection(),这意味着我们可以在 JNDI 查找之后自由设置用户名/密码。

在春天方面:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">

<jee:jndi-lookup id="dataSource"
   jndi-name="jdbc/testdb"
   cache="true"
   lookup-on-startup="true"
   expose-access-context="true">
     <property name="dataSourceProperties">
        <props>
           <prop key="user">${dataSource.username}</prop>
           <prop key="password">${passwordDecryptor.decryptedString}</prop>
        </props>
     </property>
</jee:jndi-lookup>

我相信这应该有效,或者非常接近它。我将添加到 HikariCP 以纪念 JNDI 环境的传递,以便<jee:environment>可以在<jee:jndi-lookup>标签内部使用以获得更清洁的解决方案。

于 2015-04-23T07:34:49.493 回答