最近在项目中想试一下使用 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 */@Configurationpublic 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) { MaptargetDataSources = new HashMap<>(); targetDataSources.put(DataSourceEnum.MASTER.getName(), masterDataSource); targetDataSources.put(DataSourceEnum.SLAVE.getName(), slaveDataSource); return 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]复制代码
百度了一下找到的解决方法:
- url 换成了 jdbc-url;
- 增加 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 创建数据源这个类上,而单数据源自动装载时不会出现这样的问题。