简体   繁体   English

如何在不重新启动应用程序的情况下使用新的数据库凭据连接数据库

[英]How to use the new database credentials to connect with database without restarting the application

I have a Spring application which connects with a database using ComboPooledDataSource, LocalContainerEntityManagerFactoryBean and JpaTransactionManager.我有一个 Spring 应用程序,它使用 ComboPooledDataSource、LocalContainerEntityManagerFactoryBean 和 JpaTransactionManager 连接到数据库。 The application works fine.该应用程序工作正常。 Following is my configuration.以下是我的配置。

<!-- 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>

But my database password is being rotated frequently using Hashicorp vault and I've the new password.但是我的数据库密码经常使用 Hashicorp 保险库轮换,我有新密码。 Now i need to use the new password to make connections with the database, also i need to do this without restarting the application.现在我需要使用新密码与数据库建立连接,我还需要在不重新启动应用程序的情况下执行此操作。 So is it possible to change the database credentials used in the datasource while application is running?那么是否可以在应用程序运行时更改数据源中使用的数据库凭据? If yes What should i need to do for this?如果是,我需要为此做什么? Can someone help me with this?有人可以帮我弄这个吗? Thanks.谢谢。

I think that you need to do something like that.我认为你需要做那样的事情。

public class DataSourceStateListener {
    @Autowired
    private DataSource dataSource;

    @EventListener
    public void changeDataSourceCredentials(DBCredentialsEvent event) {
        dataSource.setPassword(event.getPassword());
    } 
}

DBCredentialsEvent should be fired when new credentials has been requested from Vault.当从 Vault 请求新的凭据时,应该触发DBCredentialsEvent

@Autowired
private ApplicationEventPublisher eventPublisher;

eventPublisher(new DBCredentialsEvent(vaultPassword));

I found these lines of code in AbstractComboPooledDataSource .我在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 );
    }
}

So, it seems that changing either database user or password does reset the pool manager as well.因此,似乎更改数据库用户或密码也会重置池管理器。 Anyway, the behaviour should be tested before going to production.无论如何,应该在投入生产之前测试该行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Spring MVC Web应用程序中安全地存储数据库凭据? - How to securely store database credentials in a Spring MVC web application? 如何将我的 Docker 应用程序连接到远程数据库? - How to connect my Docker application to a remote database? 如何在没有数据库连接的情况下部署spring应用程序 - How to deploy a spring application without a database connection 从Spring应用程序停止并重新启动基于文件的H2数据库 - Stopping and restarting a file based H2 database from a Spring application 动态重新加载Spring Mongo数据库连接而无需重新启动服务器 - Dynamically Reload Spring Mongo Database Connection Without Restarting Server Spring启动应用程序如何与U2 universe数据库连接? - How to connect Spring boot application with U2 universe database? 重新加载应用程序而不重新启动Tomcat - Reload Application Without Restarting Tomcat 如何在运行时更新信任库而不在 spring 引导中重新启动应用程序 - How to update truststore at runtime without restarting the application in spring boot 如何在不重新启动应用程序的情况下重新加载 Logback SSL appenders Keystore/Truststore? - How to reload Logback SSL appenders Keystore/Truststore without restarting the application? 在 Spring Boot 应用程序中连接到多个数据库模式 - Connect to multiple database schemas in Spring boot application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM