Spring中Primary注解在项目中的解决方案

项目背景

项目采用springboot+mybatis-plus+druid。
其中druid数据源供mysql使用,信息配置在yml文件中:

spring:
  main:
    allow-bean-definition-overriding: true
  profiles:
    active: dev
  application:
    name: iotp
  datasource:
    url: jdbc:mysql://${mysql.ip}:3306/idap?characterEncoding=UTF-8&rewriteBatchedStatements=true&socketTimeout=0&allowMultiQueries=true&serverTimezone=Asia/Shanghai
    username: ${mysql.username}
    password: ${mysql.password}
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    # 使用druid数据源
    druid:
      max-active: 20
      initial-size: 1
      max-wait: 60000
      min-idle: 1
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      validation-query: SELECT 'x' FROM DUAL
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: false
      max-open-prepared-statements: 20
      # encrypt password
      #filters: config,stat,wall,log4j
      use-global-data-source-stat: true
      connection-init-sqls:
        - set names utf8mb4

问题场景

项目需要引入TDengine,于是在代码中也配置了供TDengine使用的数据源

@Configuration
public class TdengineDruidConfig {

    @Value("${tdengine.db.driverClassName}")
    private String driverClassName;
    @Value("${tdengine.db.url}")
    private String url;
    @Value("${tdengine.db.username}")
    private String username;
    @Value("${tdengine.db.password}")
    private String password;
    @Value("${tdengine.db.maxActive}")
    private String maxActive;
    @Value("${tdengine.db.initialSize}")
    private String initialSize;
    @Value("${tdengine.db.maxWait}")
    private String maxWait;
    @Value("${tdengine.db.minIdle}")
    private String minIdle;
    @Value("${tdengine.db.timeBetweenEvictionRunsMillis}")
    private String timeBetweenEvictionRunsMillis;
    @Value("${tdengine.db.minEvictableIdleTimeMillis}")
    private String minEvictableIdleTimeMillis;
    @Value("${tdengine.db.maxEvictableIdleTimeMillis}")
    private String maxEvictableIdleTimeMillis;
    @Value("${tdengine.db.validationQuery}")
    private String validationQuery;
    @Value("${tdengine.db.testWhileIdle}")
    private String testWhileIdle;
    @Value("${tdengine.db.testOnBorrow}")
    private String testOnBorrow;
    @Value("${tdengine.db.testOnReturn}")
    private String testOnReturn;


    @Bean
    public DataSource tdDatasource() {
        Properties properties = new Properties();
        properties.put("driverClassName",driverClassName);
        properties.put("url",url);
        properties.put("username",username);
        properties.put("password",password);
        properties.put("maxActive",maxActive); //maximum number of connection in the pool
        properties.put("initialSize",initialSize);//initial number of connection
        properties.put("maxWait",maxWait);//maximum wait milliseconds for get connection from pool
        properties.put("minIdle",minIdle);//minimum number of connection in the pool
        properties.put("timeBetweenEvictionRunsMillis",timeBetweenEvictionRunsMillis);// the interval milliseconds to test connection
        properties.put("minEvictableIdleTimeMillis",minEvictableIdleTimeMillis);//the minimum milliseconds to keep idle
        properties.put("maxEvictableIdleTimeMillis",maxEvictableIdleTimeMillis);//the maximum milliseconds to keep idle
        properties.put("validationQuery",validationQuery); //validation query
        properties.put("testWhileIdle",testWhileIdle); // test connection while idle
        properties.put("testOnBorrow",testOnBorrow); // don't need while testWhileIdle is true
        properties.put("testOnReturn",testOnReturn); // don't need while testWhileIdle is true
        //create druid datasource
        DataSource dataSource = null;
        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return dataSource;
    }
}

结果项目启动后,用postman调用后台接口时,原本正常的接口现在却抛出了异常,原因是数据源信息不对。

问题分析

MybatisPlusAutoConfiguration类在构建SqlSessionFactory时,需要DataSource对象。
源代码如下
在这里插入图片描述
在没有引入TDengine数据源配置前,由于项目中不存在DataSource类型的Bean,所以此处注入的DataSource对象为我们在yml中配置的;
当引入TDengine数据源后,由于代码中已经存在DataSource类型的Bean,所以此处注入的DataSource对象为我们自己定义的,就没有用到yml中的配置。

问题解决

为了让MybatisPlusAutoConfiguration类能获取到正确的DataSource对象,需要将yml中的信息配置在代码中,并加上@Primary注解标注,表示优先获取该DataSource对象。

@Configuration
public class IotpDruidConfig {
    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.druid.max-active}")
    private String maxActive;
    @Value("${spring.datasource.druid.initial-size}")
    private String initialSize;
    @Value("${spring.datasource.druid.max-wait}")
    private String maxWait;
    @Value("${spring.datasource.druid.min-idle}")
    private String minIdle;
    @Value("${spring.datasource.druid.time-between-eviction-runs-millis}")
    private String timeBetweenEvictionRunsMillis;
    @Value("${spring.datasource.druid.min-evictable-idle-time-millis}")
    private String minEvictableIdleTimeMillis;
    @Value("${spring.datasource.druid.validation-query}")
    private String validationQuery;
    @Value("${spring.datasource.druid.test-while-idle}")
    private String testWhileIdle;
    @Value("${spring.datasource.druid.test-on-borrow}")
    private String testOnBorrow;
    @Value("${spring.datasource.druid.test-on-return}")
    private String testOnReturn;
    @Value("${spring.datasource.druid.pool-prepared-statements}")
    private String poolPreparedStatements;
    @Value("${spring.datasource.druid.max-open-prepared-statements}")
    private String maxOpenPreparedStatements;
    @Value("${spring.datasource.druid.use-global-data-source-stat}")
    private String useGlobalDataSourceStat;


    @Bean
    @Primary
    public DataSource iotpDatasource() {
        Properties properties = new Properties();
        properties.put("driverClassName",driverClassName);
        properties.put("url",url);
        properties.put("username",username);
        properties.put("password",password);
        properties.put("maxActive",maxActive);
        properties.put("initialSize",initialSize);
        properties.put("maxWait",maxWait);
        properties.put("minIdle",minIdle);
        properties.put("timeBetweenEvictionRunsMillis",timeBetweenEvictionRunsMillis);
        properties.put("minEvictableIdleTimeMillis",minEvictableIdleTimeMillis);
        properties.put("validationQuery",validationQuery);
        properties.put("testWhileIdle",testWhileIdle);
        properties.put("testOnBorrow",testOnBorrow);
        properties.put("testOnReturn",testOnReturn);
        properties.put("poolPreparedStatements",poolPreparedStatements);
        properties.put("maxOpenPreparedStatements",maxOpenPreparedStatements);
        DataSource dataSource = null;
        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return dataSource;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值