天天看点

springboot 2 Hikari 多数据源配置问题(dataSourceClassName or jdbcUrl is required)

springboot 2 Hikari 多数据源配置问题(dataSourceClassName or jdbcUrl is required)

最近在项目中想试一下使用 Hikari 连接池,以前用的是阿里的 Druid,框架是 Spring MVC,xml配置文件方式注入的 Bean,现在换成 Spring Boot 之后,总遇到一些奇怪的问题,问题的根源是在于自己是个半桶水。

好了,先来看看 application.yml 配置文件:

spring:
  jpa:
    show-sql: true
  datasource:
    url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=true
    username: root
    password: root
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      maximum-pool-size: 20
      max-lifetime: 30000
      idle-timeout: 30000
      data-source-properties:
        prepStmtCacheSize: 250
        prepStmtCacheSqlLimit: 2048
        cachePrepStmts: true
        useServerPrepStmts: true
    slave:
      url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=true
      username: root
      password: root
      type: com.zaxxer.hikari.HikariDataSource
      hikari:
        maximum-pool-size: 20
        max-lifetime: 30000
        idle-timeout: 30000
        data-source-properties:
          prepStmtCacheSize: 250
          prepStmtCacheSqlLimit: 2048
          cachePrepStmts: true
          useServerPrepStmts: true
复制代码      

数据源配置文件:

package org.seckill.config;
      

​import com.zaxxer.hikari.HikariDataSource;​

​​

​import org.slf4j.Logger;​

​import org.slf4j.LoggerFactory;​

​import org.springframework.beans.factory.annotation.Qualifier;​

​import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;​

​import org.springframework.boot.context.properties.ConfigurationProperties;​

​import org.springframework.boot.jdbc.DataSourceBuilder;​

​import org.springframework.context.annotation.Bean;​

​import org.springframework.context.annotation.Configuration;​

​import org.springframework.context.annotation.Primary;​

​import org.springframework.jdbc.core.JdbcTemplate;​

​ ​

​import javax.sql.DataSource;​

​import java.util.HashMap;​

​import java.util.Map;​

​ ​

​/**​

​ ​

​ ​

​数据源配置​

​ ​

​@author jeftom​

​ ​

​@date 2019-04-14 12:03​

​ ​

​ ​

​@since 1.0.0​

​*/​

​@Configuration​

​public class DataSourceConfig {​

​private final static Logger LOGGER = LoggerFactory.getLogger(DataSourceConfig.class);​

​ ​

​@Bean(name = "masterDataSource")​

​@ConfigurationProperties(prefix = "spring.datasource")​

​public DataSource masterDataSource(DataSourceProperties properties) {​

​LOGGER.info("init master data source:{}", properties);​

​return DataSourceBuilder.create().build();​

​}​

​ ​

​@Bean(name = "slaveDataSource")​

​@ConfigurationProperties(prefix = "spring.datasource.slave")​

​public DataSource slaveDataSource(DataSourceProperties properties) {​

​LOGGER.info("init slave data source:{}", properties);​

​return DataSourceBuilder.create().build();​

​}​

​ ​

​@Bean​

​@Primary​

​public DynamicDataSource dataSource(DataSource masterDataSource, DataSource slaveDataSource) {​

​Map<String, DataSource> targetDataSources = new HashMap<>();​

​targetDataSources.put(DataSourceEnum.MASTER.getName(), masterDataSource);​

​targetDataSources.put(DataSourceEnum.SLAVE.getName(), slaveDataSource);​

​ ​

<span ><span >return</span></span> new DynamicDataSource(masterDataSource, targetDataSources);
      

​ ​

​}​

​}​

​复制代码​

报错信息:

com.zaxxer.hikari.HikariConfig           : HikariPool-1 - dataSource or dataSourceClassName or jdbcUrl is required.

java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
    at com.zaxxer.hikari.HikariConfig.validate(HikariConfig.java:955) ~[HikariCP-3.2.0.jar:na]
复制代码      

百度了一下找到的解决方法:

  1. url 换成了 jdbc-url;
  2. 增加 driver-class-name: com.mysql.cj.jdbc.Driver

试了一下,果然真的可以。但是,没有使用多数据源时,原来的配置文件也是能正常使用的啊,为什么呢?

问题肯定是出在增加了 DataSourceConfig 这个配置文件之后。

于是试着把配置文件还原回去,再把

return DataSourceBuilder.create().build();
复制代码      

改为如下:

return DataSourceBuilder.create(properties.getClassLoader())
                .type(HikariDataSource.class)
                .driverClassName(properties.determineDriverClassName())
                .url(properties.determineUrl())
                .username(properties.determineUsername())
                .password(properties.determinePassword())
                .build();
复制代码      

也就是从配置文件拿到配置值之后重新赋值一下,再次启动项目,居然好了~

原因就是出在 DataSourceBuilder 创建数据源这个类上,而单数据源自动装载时不会出现这样的问题。

继续阅读