1. 程式人生 > 程式設計 >詳解MybatisPlus整合nacos導致druid連線不上資料庫

詳解MybatisPlus整合nacos導致druid連線不上資料庫

問題

mp加密與druid和nacos結合,首次專案啟動成功,後續訪問無法連線資料庫

導致原因

專案首次載入由於會去nacos讀取一遍配置,剛好mp啟動的時候也會去讀取配置好key值,所以啟動的時候不會報錯
由於nacos有自動重新整理配置功能,後面自動重新整理的時候mp不會再讀取命令列配置key,導致無法解密,從而連線資料庫失敗

解決方案

知道原因之後,我們可以修改druid連線資料庫的配置,因為druid自帶資料庫加解密,參考ConfigFilter類就可以知道,druid會去讀取外部的配置檔案,可以通過這種方法解決

注意事項

  • 由於mp這個配置的key值只會讀取一次,通過SafetyEncryptProcessor這個類來解密。後續是儲存在MapPropertySource這裡面,原始碼得知
  • druid的過濾器比mp寫的解密還要先執行,這個是重點,因為key只讀取一次,而且過濾器也只會執行一次,所以不能從mp下手
  • 交換bean的注入順序也無法解決(大概原因是druid過濾器比mp執行還要優先,此處不知道是否有新的解決方案)

附原始碼

package com.hpf.cloud.filter;

import com.alibaba.druid.filter.config.ConfigFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
import com.baomidou.mybatisplus.core.toolkit.AES;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.stereotype.Component;

import java.sql.SQLException;
import java.util.Properties;

/**
 * @description: 相容druid與mp加解密,重寫druid的解密,替換為mp的解密方式
 * @datetime: 2020/11/22 16:12
 * @author: huangpengfei
 */
@NoArgsConstructor
@Slf4j
@Component
public class DruidForMybatisPlusDecryptFilter extends FilterAdapter {

  /**
   * 獲取命令列中的key
   */
  @Autowired
  private ConfigurableEnvironment configurableEnvironment;

  /**
   * 重寫獲取密碼解密
   * 1. 參考DruidFilter的程式碼,取的是file型別的配置檔案,這裡從啟動引數中獲取即可
   * 2. 如果不配置,且不需要解密則放行
   *
   * @param dataSourceProxy
   */
  @Override
  public void init(DataSourceProxy dataSourceProxy) {
    if (!(dataSourceProxy instanceof DruidDataSource)) {
      log.error("ConfigLoader only support DruidDataSource");
    }
    DruidDataSource dataSource = (DruidDataSource) dataSourceProxy;
    String mpwKey = null;
    for (PropertySource<?> ps : configurableEnvironment.getPropertySources()) {
      if (ps instanceof SimpleCommandLinePropertySource) {
        SimpleCommandLinePropertySource source = (SimpleCommandLinePropertySource) ps;
        mpwKey = source.getProperty("mpw.key");
        break;
      }
    }
    if (null != mpwKey) {
      // 證明加密
      Properties properties = this.setProperties(dataSource,mpwKey);
      try {
        // 將資訊配置進druid
        DruidDataSourceFactory.config(dataSource,properties);
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
    log.info("資料庫連線成功!");
  }

  /**
   * 通過命令列的金鑰進行解密
   *
   * @param dataSource 資料來源
   * @param mpwKey   解密key
   * @return
   */
  private Properties setProperties(DruidDataSource dataSource,String mpwKey) {
    Properties properties = new Properties();
    // 先解密
    try {
      String userName = AES.decrypt(dataSource.getUsername().substring(4),mpwKey);
      properties.setProperty(DruidDataSourceFactory.PROP_USERNAME,userName);
      dataSource.setUsername(userName);
      String password = AES.decrypt(dataSource.getPassword().substring(4),mpwKey);
      properties.setProperty(DruidDataSourceFactory.PROP_PASSWORD,password);
      dataSource.setPassword(password);
      String url = AES.decrypt(dataSource.getUrl().substring(4),mpwKey);
      properties.setProperty(DruidDataSourceFactory.PROP_URL,url);
      dataSource.setUrl(url);
    } catch (Exception e) {
      log.info("druid decrypt failed!");
      e.printStackTrace();
    }
    return properties;
  }

}

ps
nacos整合後一直重新整理配置,頻率很高,這是因為版本問題,修改客戶端和服務端的版本即可

到此這篇關於詳解MybatisPlus整合nacos導致druid連線不上資料庫的文章就介紹到這了,更多相關MybatisPlus druid連線不上內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!