大体思路:
改写连接池获取数据库连接的方法,捕获异常时改写环境中及配置文件的密码.
- 找到连接池获取数据库连接的类(创建新连接时会报密码错误的类)
- 复制该类源码到项目相同路径下(路径需要创建)
- 找到数据库连接抛出登录失败异常的方法,处理该异常(捕获登录失败的异常,不同数据库的异常信息也不一样,需自行修改)
- 修改环境中已读取的配置及本地配置(环境中的数据库连接配置也要改,读取的密码是否加解密按需修改)
较适用于war包及可修改外部公用配置文件的应用
//以下为hikari连接池解决方法
@Override
public Connection getConnection(final String username, final String password) throws SQLException
{
final Properties cloned = (Properties) driverProperties.clone();
if (username != null) {
cloned.put("user", username);
if (cloned.containsKey("username")) {
cloned.put("username", username);
}
}
if (password != null) {
cloned.put("password", password);
}
Connection connect = null;
try{
connect = driver.connect(jdbcUrl, cloned);
}catch (Exception e){
//获取连接时异常,判断是否密码错误引起.sqlserver抛出此异常,按需求判断
if (e.getMessage().indexOf("登录失败")!=-1){
//加载新的配置文件
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("application.properties");
Properties properties = new Properties();
try {
properties.load(inputStream);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
//获取密码
String property = properties.getProperty("spring.datasource.password");
if (property.indexOf("(")!=-1){
property=property.substring(property.indexOf("(")+1,property.indexOf(")"));
}
String newPwd="";
try {
//解密
newPwd= Decode.decodeStr(property);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
//新密码放入应用环境中
System.getProperties().setProperty("spring.datasource.password",newPwd);
driverProperties.setProperty("password",newPwd);
cloned.setProperty("password",newPwd);
connect= driver.connect(jdbcUrl,cloned);
}
}
return connect;
}
//以下为dbcp连接池解决方法
public Connection getConnection() throws SQLException {
Connection connection ;
try {
connection = createDataSource().getConnection();
}catch (Exception e){
if(e.getMessage().indexOf("登录失败")!=-1){
try {
Resource resource = new DefaultResourceLoader().getResource("datasource.properties");
Properties properties = new Properties();
properties.load(resource.getInputStream());
new EncryptablePropertyPlaceholderConfigurer().processProperties(configurableListableBeanFactory,properties);
this.dataSource=null;
addConnectionProperty("password", properties.getProperty("dataSource.password"));
password=properties.getProperty("dataSource.password");
} catch (IOException ex) {
throw new RuntimeException(ex);
}
connection = createDataSource().getConnection();
}
else {
throw e;
}
}
return connection;
}
//以下为druid解决方案
public Connection createPhysicalConnection(String url, Properties info) throws SQLException, IOException {
Object conn ;
if (this.getProxyFilters().size() == 0) {
try {
conn = this.getDriver().connect(url, info);
}catch (Exception e){
//密码修改后连接不可用抛出异常登录失败
if(e.getMessage().indexOf("登录失败")!=-1){
//加载新的配置文件
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("config/application.properties");
Properties properties = new Properties();
properties.load(inputStream);
//获取密码
String property = properties.getProperty("spring.datasource.password");
if (property.indexOf("(")!=-1){
property=property.substring(property.indexOf("(")+1,property.indexOf(")"));
}
String newPwd="";
try {
//解密
newPwd=Decode.decodeStr(property);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
//新密码放入应用环境中
System.getProperties().setProperty("spring.datasource.password",newPwd);
//使用新密码获取连接
info.setProperty("password",newPwd);
conn=getDriver().connect(url,info);
}
else {
throw e;
}
}
} else {
try {
conn = (new FilterChainImpl(this)).connection_connect(info);
}catch (Exception e){
if(e.getMessage().indexOf("登录失败")!=-1){
InputStream inputStream = this.getClass().getResourceAsStream("config/application.properties");
Properties properties = new Properties();
properties.load(inputStream);
String property = properties.getProperty("spring.datasource.password");
String newPwd="";
try {
newPwd=Decode.decodeStr(property);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
System.getProperties().setProperty("spring.datasource.password",newPwd);
info.setProperty("password",newPwd);
conn=new FilterChainImpl(this).connection_connect(info);
}
else {
throw e;
}
}
}
createCountUpdater.incrementAndGet(this);
return (Connection)conn;
}