HikariConfig初始化分析

歡迎訪問個人博客,同步更新: 楓山別院數據庫

源代碼版本2.4.5-SNAPSHOTthis

HikariConfig有 3 個構造方法,這三個構造方法其實都差很少,無咱們逐個看一下:code

無參構造

第一個無參的構造,代碼以下:get

public HikariConfig() {
      dataSourceProperties = new Properties();
      healthCheckProperties = new Properties();
      //①
      minIdle = -1;
      maxPoolSize = -1;
      maxLifetime = MAX_LIFETIME;
      connectionTimeout = CONNECTION_TIMEOUT;
      validationTimeout = VALIDATION_TIMEOUT;
      idleTimeout = IDLE_TIMEOUT;

      isAutoCommit = true;
      isInitializationFailFast = true;
      //②
      String systemProp = System.getProperty("hikaricp.configurationFile");
      if (systemProp != null) {
         loadProperties(systemProp);
      }
   }
  • ①初始化默認值

初始化默認值這部分,這些參數咱們在《HikariConfig的配置解析》一文中都解析過這些參數,略過不提。同步

  • ②獲取配置文件地址

在這裏首先嚐試獲取key 是hikaricp.configurationFile的配置文件地址,若是用戶配置了,就會加載。咱們能夠在啓動應用的時候使用-D指定。博客

咱們詳細看下loadProperties方法:string

protected void loadProperties(String propertyFileName) {
      //①將propertyFileName看成一個路徑, 直接加載文件
      final File propFile = new File(propertyFileName);
      //②判斷propFile是一個文件, 就直接讀取; 不是文件, 就繼續查找, 加載不到, 直接報錯
      try (final InputStream is = propFile.isFile() ? new FileInputStream(propFile) : this.getClass().getResourceAsStream(propertyFileName)) {
         if (is != null) {
            Properties props = new Properties();
            props.load(is);
            //③
            PropertyElf.setTargetFromProperties(this, props);
         } else {
            throw new IllegalArgumentException("Cannot find property file: " + propertyFileName);
         }
      } catch (IOException io) {
         throw new RuntimeException("Failed to read property file", io);
      }
   }
  • ①加載文件

嘗試將propertyFileName看成一個路徑, 直接加載文件it

  • ②查找文件

在此判斷propFile是否是一個文件, 是文件就直接讀取; 不是文件, 就繼續查找。若是最後仍是 加載不到, 直接直接報錯。io

  • ③獲取屬性

將Properties文件中的配置,取出來 set 到HikariConfig中。ast

配置賦值

咱們看下實現:

public static void setTargetFromProperties(final Object target, final Properties properties) {
      if (target == null || properties == null) {
         return;
      }
      //①獲取HikariConfig中的全部方法
      List<Method> methods = Arrays.asList(target.getClass().getMethods());
      //獲取properties配置文件的全部配置項名稱的集合, 例如dataSource.username = tom , 此處拿到的是dataSource.username這種等號左邊的全部配置項
      Enumeration<?> propertyNames = properties.propertyNames();
      //遍歷全部的配置項, 複製到HikariConfig中
      while (propertyNames.hasMoreElements()) {
         Object key = propertyNames.nextElement();
         String propName = key.toString();
         //獲取配置項對應的值
         Object propValue = properties.getProperty(propName);
         if (propValue == null) {
            propValue = properties.get(key);
         }
         //②若是不是HikariConfig的配置, 是dataSource的配置, 也就是數據庫相關的配置, 就添加到DataSourceProperty中
         // 由於每一個數據庫的配置可能不同, 全部沒有 setter 方法
         if (target instanceof HikariConfig && propName.startsWith("dataSource.")) {
            ((HikariConfig) target).addDataSourceProperty(propName.substring("dataSource.".length()), propValue);
         } else {
            //③若是不是 dataSource配置, 那就調用 setter 方法, 給HikariConfig賦值
            setProperty(target, propName, propValue, methods);
         }
      }
   }

在①處,經過反射獲取到HikariConfig的全部方法,而後獲取properties文件中因此的 key 值,遍歷properties文件中的 全部key,將配置項一項一項的設置到HikariConfig中。

註釋很是詳細,可是要提醒你們的是,並非全部的配置,HikariCP 都有對應的屬性,有一些數據庫獨有的配置項,咱們一般是使用dataSource.XXX來配置的,因此若是在properties文件中有以dataSource.開頭的配置項,那麼就是dataSource的配置,要放到

DataSourceProperty中,這些配置沒有對應的 setter。③處的setProperty方法,就是一個比較普通的反射方式賦值的實現,你們看一下就能夠了。

相關文章
相關標籤/搜索