1. 注入
@Autowired
private DruidDataSource druidDataSource ;
2.修改属性
druidDataSource .setPassword('newpassword');
druidDataSource .restart();
________________________________________________
1. 利用 DruidPasswordCallback 接口动态修改密码
Druid passwordcallback失效
引入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</ artifactId>
<version>1.1.21</version>
</ dependency>
配置如下:
spring:
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test
username: root
druid:
connectionProperties: password=加密后的密码 #自定义加密方式
passwordCallbackClassName: com.sgcc.psr.DBPasswordCallback #回调类的路径
回调类DBPasswordCallback 代码如下:
/** *需要继承DruidPasswordCallback 并重写setProperties 方法 **/
public class DBPasswordCallback extends DruidPasswordCallback {
@Override
public void setProperties(Properties properties) {
super.setProperties(properties);
//获取配置文件中加密后的密码,和xml中的connectionProperties属性配置相关
String password = (String) properties.get("password");
try {
//解密过程,ConfigTools为druid自带,提供一些好用的函数
String dbpassword= ConfigTools.decrypt(publicKey,password);
//设置密码
setPassword(dbpassword.toCharArray());
}catch (Exception e){
e.printStackTrace();
}
}
}
启动失败,报错提示密码错误。
猜想是密码解密失败,进入到druid.jar断点调试,发现没有进入druidDatasource中的passwordCallback方法。
解决办法:
换成springboot集成的druid依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</ artifactId>
<version>1.1.21</version>
</ dependency>
______________________________________________________________________________________________________
2. 利用 datasource.init() 方法修改密码后重新初始化
Druid源码阅读1-DruidDataSource之init()
https://blog.csdn.net/suxiao_21/article/details/124679504
Druid源码阅读2-DruidDataSource的init过程
https://blog.csdn.net/dhaibo1986/article/details/121233998
______________________________________________________________________________________________________
动态密码修改参考方案:
//1.配置 new DBPasswordCallback(sourceKey, username)package cn.com.wind.wstockactivity.infrastructure.core.database.mysqldatasource; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.alibaba.druid.filter.Filter; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.wall.WallConfig; import com.alibaba.druid.wall.WallFilter; import cn.com.wind.wstockactivity.infrastructure.core.database.DBPasswordCallback; import cn.com.wind.wstockactivity.infrastructure.core.windtools.dbpwdService.PasswordServiceHelper; @Configuration public class MasterMySqlDataSourceConfig { @Value("${spring.datasource.master.sourceKey}") private String sourceKey; @Value("${spring.datasource.master.jdbc-url}") private String dbUrl; @Value("${spring.datasource.master.username}") private String username; @Value("${spring.datasource.master.password}") private String password; @Value("${spring.datasource.master.driver-class-name}") private String driverClassName; @Value("${spring.datasource.master.initialSize}") private int initialSize; @Value("${spring.datasource.master.minIdle}") private int minIdle; @Value("${spring.datasource.master.maxActive}") private int maxActive; @Value("${spring.datasource.master.maxWait}") private int maxWait; @Value("${spring.datasource.master.timeBetweenEvictionRunsMillis}") private int timeBetweenEvictionRunsMillis; @Value("${spring.datasource.master.minEvictableIdleTimeMillis}") private int minEvictableIdleTimeMillis; @Value("${spring.datasource.master.validationQuery}") private String validationQuery; @Value("${spring.datasource.master.testWhileIdle}") private boolean testWhileIdle; @Value("${spring.datasource.master.testOnBorrow}") private boolean testOnBorrow; @Value("${spring.datasource.master.testOnReturn}") private boolean testOnReturn; @Value("${spring.datasource.master.poolPreparedStatements}") private boolean poolPreparedStatements; @Value("${spring.datasource.master.maxPoolPreparedStatementPerConnectionSize}") private int maxPoolPreparedStatementPerConnectionSize; @Value("${spring.datasource.master.filters}") private String filters; @Value("${spring.datasource.master.connectionProperties}") private String connectionProperties; @Value("${spring.datasource.master.useGlobalDataSourceStat}") private boolean useGlobalDataSourceStat; @Bean(name = "primaryMasterDataSource") // 声明其为Bean实例 public DataSource dataSource() { DruidDataSource datasource = new DruidDataSource(); // 密码信息 password = PasswordServiceHelper.getPassword(sourceKey, username); datasource.setUrl(this.dbUrl); datasource.setUsername(username); datasource.setPassword(password); datasource.setDriverClassName(driverClassName); datasource.setPasswordCallback(new DBPasswordCallback(sourceKey, username)); // configuration datasource.setInitialSize(initialSize); datasource.setMinIdle(minIdle); datasource.setMaxActive(maxActive); datasource.setMaxWait(maxWait); datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); datasource.setValidationQuery(validationQuery); datasource.setTestWhileIdle(testWhileIdle); datasource.setTestOnBorrow(testOnBorrow); datasource.setTestOnReturn(testOnReturn); datasource.setPoolPreparedStatements(poolPreparedStatements); datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); datasource.setUseGlobalDataSourceStat(useGlobalDataSourceStat); try { datasource.setFilters(filters); } catch (SQLException e) { System.err.println(" MasterMySqlDataSourceConfig, druid configuration initialization filter: " + e); } WallConfig wallconfig = new WallConfig(); wallconfig.setMultiStatementAllow(true);// 允许多SQL wallconfig.setNoneBaseStatementAllow(true); // 允许非基础SQL WallFilter wallFilter = new WallFilter(); wallFilter.setConfig(wallconfig); List<Filter> filterList = new ArrayList<Filter>(); filterList.add(wallFilter); datasource.setProxyFilters(filterList); datasource.setConnectionProperties(connectionProperties); return datasource; } public String getSourceKey() { return sourceKey; } public String getUsername() { return username; } }//2.配置 DBPasswordCallback
package cn.com.wind.wstockactivity.infrastructure.core.database; import java.util.Properties; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.druid.util.DruidPasswordCallback; import cn.com.wind.wstockactivity.infrastructure.core.windtools.dbpwdService.PasswordServiceHelper; public class DBPasswordCallback extends DruidPasswordCallback { private static final long serialVersionUID = 6540791084537255345L; private String userName; private String pwdDbName; private Logger logger = LoggerFactory.getLogger(getClass()); public DBPasswordCallback(String pwdDbName, String userName) { this.pwdDbName = pwdDbName; this.userName = userName; } @Override public void setProperties(Properties properties) { super.setProperties(properties); String pwd = properties.getProperty("password"); try { String cryptoPwd = PasswordServiceHelper.getLastedPassword(pwdDbName, userName); logger.info("Crypto " + cryptoPwd); if (StringUtils.isBlank(cryptoPwd)) { setPassword(pwd.toCharArray()); } else { setPassword(cryptoPwd.toCharArray()); } } catch (Exception e) { logger.error(e.getMessage()); setPassword(pwd.toCharArray()); } } }