七、HikariConfig 初始化分析

本文分析了HikariConfig的无参构造方法,详细介绍了配置文件的加载过程,包括尝试从系统属性中获取配置文件路径,加载并解析Properties文件到HikariConfig。接着,文章探讨了配置赋值的过程,通过反射将properties文件中的配置项设置到HikariConfig对象中,特别指出非所有配置都有对应的setter方法,对于dataSource开头的配置会作为特殊处理。

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值