错误记录:expected single matching bean but found 2

本文详细解析了在SpringBoot项目中如何同时配置并使用MySQL和ClickHouse数据源,通过添加配置Bean解决数据源冲突问题,并确保应用可以正确区分和使用不同的数据源。

springboot项目,之前有mysql数据源,现在又新增了clickhouse数据源,于是

新增了一个clickhouseDatasource的配置bean,如下:

	@Bean
    public DataSource dataSource() throws PropertyVetoException {
        HikariConfig config = new HikariConfig();
        String jdbcUrl = ConfigCentre.getString(ConfigConst.EC_MYSQL_URL);

        if (StringUtils.isBlank(jdbcUrl)) {
            return null;
        }
        String userName = ConfigCentre.getString(ConfigConst.EC_MYSQL_USERNAME);
        String password = ConfigCentre.getString(ConfigConst.EC_MYSQL_PASSWORD);
        config.setJdbcUrl(jdbcUrl);
        config.setUsername(userName);
        config.setPassword(password);
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        HikariDataSource dataSource = new HikariDataSource(config);
        return dataSource;
    }
	@Bean
    public ClickHouseDataSource getClickHouseDataSource(){
        ClickHouseProperties properties = new ClickHouseProperties();
        properties.setDataTransferTimeout(5*60*1000);
        properties.setMaxExecutionTime(5*60*1000);
        properties.setUseTimeZone("UTC");
        properties.setUseServerTimeZone(false);
        ClickHouseDataSource clickHouseDataSource = new ClickHouseDataSource(CLICKHOUSEFORADRESPONSEURL, properties);
        return clickHouseDataSource;
    }

用这个bean的时候:

	@@Autowired
    private ClickHouseDataSource clickHouseDataSource;

但是这样就报错了,如下:

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getClickHouseDataSource' defined in com.yeahmobi.dsp.DBBeans: 
Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': 
Invocation of init method failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: dataSource,getClickHouseDataSource

主要提示在DataSource … but but found 2:dataSource,getClickHouseDataSource

最后发现,是因为Spring认为这两个bean是同一类型的bean

看ClickHouseDataSource这个类的源码:

public class ClickHouseDataSource implements DataSource{
	...
}

看上面那个DataSource返回的真正实体类:HikariDataSource源码(注:Hikari连接池,号称是java平台最快的,替换druid)

public class HikariDataSource extends HikariConfig implements DataSource, Closeable {
	...
}

发现ClickHouseDataSource也是实现了DataSource类,而上面那个HikariDataSource也是实现了HikariDataSource ,所以这也算bean重复了。所以得在Bean定义的时候分别申明。
但由于之前这个DataSource,已经有很多地方在用了,改的时候不方便,所以就采用默认是HikariDataSource,用ClickHouseDataSource的时候,再手动申明的策略。

解决:

原来DataSource的Bean定义上,再加注解@Primary,如下:

@Bean
    @Primary
    public DataSource dataSource() throws PropertyVetoException {
        ......
        return dataSource;
    }

用到ClickhouseDataSource Bean的地方,用@Resource注入,指明name是哪个方法名。

	@Resource(name = "getClickHouseDataSource")
    private ClickHouseDataSource clickHouseDataSource;

再次启动,ok

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值