springboot 2 Hikari 多數據源配置問題(dataSourceClassName or jdbcUrl is required)

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);

		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

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

  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 創建數據源這個類上,而單數據源自動裝載時不會出現這樣的問題。

如果使用druid數據源,那麼改成如下也可以。

    @Bean
    @ConfigurationProperties("spring.datasource")
    public DataSource defaultDataSource(){
//        <dependency>
//			<groupId>com.alibaba</groupId>
//			<artifactId>druid-spring-boot-starter</artifactId>
//			<version>1.1.10</version>
//		</dependency>
        return DruidDataSourceBuilder.create().build();

    }

對應的pom文件加

        <dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.10</version>
		</dependency>

或者使用標準的datasource

@Primary
@Bean
public DataSource customDataSource() {

    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(env.getProperty("custom.datasource.driver-class-name"));
    dataSource.setUrl(env.getProperty("custom.datasource.url"));
    dataSource.setUsername(env.getProperty("custom.datasource.username"));
    dataSource.setPassword(env.getProperty("custom.datasource.password"));

    return dataSource;

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章