我有一个Spring应用程序,它使用ComboPooledDataSource、LocalContainerEntityManagerFactoryBean和JpaTransactionManager与数据库连接。该应用程序运行良好。以下是我的配置。
<!-- DataSource JavaConfig -->
@Configuration
public class DataSourceConfig
{
@Bean
public DataSource dataSource()
{
try {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(getUsername());
dataSource.setPassword(getPassword());
dataSource.setDriverClass(driverClassName);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setMinPoolSize(minPoolSize);
dataSource.setMaxPoolSize(maxPoolSize);
dataSource.setCheckoutTimeout(checkoutTimeout);
dataSource.setMaxIdleTime(maxIdleTime);
dataSource.setIdleConnectionTestPeriod(idleConnectionTestPeriod);
dataSource.setAcquireRetryAttempts(acquireRetryAttempts);
dataSource.setAcquireRetryDelay(acquireRetryDelay);
return dataSource;
} catch (Exception ex) {
LOGGER.error("Error occurred while initializing datasource ", ex);
}
return null;
}
}
<!-- Transaction Manager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- Entity manager factory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="dbMigrationService">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceUnitManager" ref="persistenceUnitManager"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="${hibernate.showSql}"/>
<property name="databasePlatform" value="${hibernate.dialect}"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<!-- batch writing -->
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
<prop key="hibernate.order_inserts">${hibernate.order_inserts}</prop>
<prop key="hibernate.order_updates">${hibernate.order_updates}</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
</props>
</property>
</bean>
但我的数据库密码经常使用Hashicorp保管库进行轮换,我有了新密码。现在我需要使用新密码与数据库建立连接,而且我需要在不重新启动应用程序的情况下完成此操作。所以,在应用程序运行时,是否可以更改数据源中使用的数据库凭据?如果是,我该怎么办?有人能帮我吗?谢谢
我认为您需要这样做。
public class DataSourceStateListener {
@Autowired
private DataSource dataSource;
@EventListener
public void changeDataSourceCredentials(DBCredentialsEvent event) {
dataSource.setPassword(event.getPassword());
}
}
从Vault请求新凭据时,应激发DBCredentialsEvent
。
@Autowired
private ApplicationEventPublisher eventPublisher;
eventPublisher(new DBCredentialsEvent(vaultPassword));
我在AbstractComboPooledDataSource
中找到了这些代码行。
public void setUser( String user ) {
if ( diff( dmds.getUser(), user ) ) {
dmds.setUser( user );
this.resetPoolManager( false );
}
}
public void setPassword( String password ) {
if ( diff( dmds.getPassword(), password ) ) {
dmds.setPassword( password );
this.resetPoolManager( false );
}
}
因此,更改数据库用户或密码似乎也会重置池管理器。无论如何,在投入生产之前,应该对其性能进行测试。