写点什么

七、HikariConfig 初始化分析

作者:阿白
  • 2022 年 7 月 29 日
  • 本文字数:2032 字

    阅读完需:约 7 分钟

七、HikariConfig初始化分析

欢迎访问我的博客,同步更新: 枫山别院


源代码版本 2.4.5-SNAPSHOT


HikariConfig有 3 个构造方法,这三个构造方法其实都差不多,无我们逐个看一下:

无参构造

第一个无参的构造,代码如下:


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方法:


   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 当作一个路径, 直接加载文件


  • ②查找文件


在此判断 propFile 是不是一个文件, 是文件就直接读取; 不是文件, 就继续查找。如果最后还是 加载不到, 直接直接报错。


  • ③获取属性


将 Properties 文件中的配置,取出来 set 到HikariConfig中。

配置赋值

我们看下实现:


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方法,就是一个比较普通的反射方式赋值的实现,大家看一下就可以了。

发布于: 刚刚阅读数: 3
用户头像

阿白

关注

爱生活,爱代码 2020.03.25 加入

有两样东西,越是经常而持久地对它们进行反复思考,它们就越是使心灵充满常新而日益增长的惊赞和敬畏:我头上的星空和我心中的道德法则——康德

评论

发布
暂无评论
七、HikariConfig初始化分析_数据库_阿白_InfoQ写作社区