关于 hikari 多数据源配置的坑
Jihongchang(讨论 | 贡献)2023年2月17日 (五) 09:09的版本
application.yml
spring:
datasource:
hikari:
datasource-world:
jdbc-url: jdbc:mysql://127.0.0.1:3306/world
username: root
password: 123456
datasource-testdb:
jdbc-url: jdbc:mysql://127.0.0.1:3306/testdb
username: root
password: 123456
DataSourceTestdbConfig.java
package io.github.jihch.config;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "io.github.jihch.mapper.testdb", sqlSessionTemplateRef = "sqlSessionTemplateTestdb")
public class DataSourceTestdbConfig {
@Bean("dataSourceTestdb")
@ConfigurationProperties(prefix = "spring.datasource.hikari.datasource-testdb")
public DataSource dataSourceTestdb() {
return new HikariDataSource();
}
@Bean
public SqlSessionFactory sqlSessionFactoryTestdb(@Qualifier("dataSourceTestdb") HikariDataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplateTestdb(@Qualifier("sqlSessionFactoryTestdb") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
DataSourceWorldConfig.java
package io.github.jihch.config;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "io.github.jihch.mapper.world", sqlSessionTemplateRef = "sqlSessionTemplateWorld")
public class DataSourceWorldConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari.datasource-world")
public DataSource dataSourceWorld() {
return new HikariDataSource();
}
@Bean
public SqlSessionFactory sqlSessionFactoryWorld(@Qualifier("dataSourceWorld") HikariDataSource dataSource)
throws Exception {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplateWorld(@Qualifier("sqlSessionFactoryWorld") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
这套多数据源配置在启动的时候一直在抛异常
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.zaxxer.hikari.HikariDataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=dataSourceWorld)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.13.jar:5.3.13]
... 20 common frames omitted
定位半天发现容器里 type=javax.sql.DataSource 的对象两个都在 dataSourceTestdb 和 dataSourceWorld;
但是 type=HikariDataSource 的对象就只有 dataSourceTestdb 一个,dataSourceWorld 没有算在内;
试了试把注入到 SqlSessionFactory 的 Bean 定义方法的入参类型改成 javax.sql.DataSource 就没问题了。