数据库密码修改感知热更新

大体思路:

        改写连接池获取数据库连接的方法,捕获异常时改写环境中及配置文件的密码.

  1. 找到连接池获取数据库连接的类(创建新连接时会报密码错误的类)
  2. 复制该类源码到项目相同路径下(路径需要创建)
  3. 找到数据库连接抛出登录失败异常的方法,处理该异常(捕获登录失败的异常,不同数据库的异常信息也不一样,需自行修改)
  4. 修改环境中已读取的配置及本地配置(环境中的数据库连接配置也要改,读取的密码是否加解密按需修改)

         较适用于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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值