栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

阿里生态项目加入Activiti7遇到初始化异常的问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

阿里生态项目加入Activiti7遇到初始化异常的问题

在阿里生态项目(nacos/dubbo/sentinel/seata)里面加入Activiti7,出现下面异常,初始化拿不到数据库链接

排查的过程一波三折,经过一番捣鼓发现是druid的连接抛出的异常:
com.alibaba.druid.pool.DruidPooledConnection#setSchema
public void setSchema(String schema) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
我用的是默认的HikariDataSource,怎么冒出个druid??查依赖。

翻查依赖树发现spring-cloud-starter-alibaba-nacos-config和seata-all两个包依赖了druid,于是在依赖里面排除druid,启动正常了。

于是就发了一条issue给seata,得到的回复是seata依赖druid是为了用它的sqlparser, 也就是说,用排除Druid的方法是不能真正解决问题的,会给seata带来异常隐患!

因为看依赖树并没发现有druid-spring-boot-starter,也并没在配置里面有druid的参数,理应不会自动配置druidsource的!于是再继续查!

最后发现依赖里面的baomidou动态数据源导致:

  • com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceCreatorAutoConfiguration.DruidDataSourceCreatorConfiguration#druidDataSourceCreator
    只要发现有druid的依赖就会建立DruidDataSourceCreator
    @ConditionalOnClass(DruidDataSource.class)
    @Configuration
    public class DruidDataSourceCreatorConfiguration {
        @Bean
        @Order(DRUID_ORDER)
        @ConditionalOnMissingBean
        public DruidDataSourceCreator druidDataSourceCreator() {
            return new DruidDataSourceCreator(properties);
        }

    }

    
    @ConditionalOnClass(HikariDataSource.class)
    @Configuration
    public class HikariDataSourceCreatorConfiguration {
        @Bean
        @Order(HIKARI_ORDER)
        @ConditionalOnMissingBean
        public HikariDataSourceCreator hikariDataSourceCreator() {
            return new HikariDataSourceCreator(properties);
        }
    }

最后将兼容的Datasource收集到com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator.creators
然后做匹配,因为Druid先于Hikari,所以就抢占了:

public DataSource createDataSource(DataSourceProperty dataSourceProperty) {
        DataSourceCreator dataSourceCreator = null;
        for (DataSourceCreator creator : this.creators) {
            if (creator.support(dataSourceProperty)) {
                dataSourceCreator = creator;
                break;
            }
        }
        if (dataSourceCreator == null) {
            throw new IllegalStateException("creator must not be null,please check the DataSourceCreator");
        }
        return dataSourceCreator.createDataSource(dataSourceProperty);
    }

找到原因就好办,DataSourceCreattor要通过support返回当前creator是否支持app配置,而其中会用上type这个条件:

@Override
    public boolean support(DataSourceProperty dataSourceProperty) {
        Class type = dataSourceProperty.getType();
        return (type == null && druidExists) || (type != null && DRUID_DATASOURCE.equals(type.getName()));
    }

所以,最终完美的解决方法不是用pom排除,也不是放弃使用动态数据源,而是在配置文件中指定type:

spring:
  datasource:
    dynamic:
      primary: master
      strict: false
      datasource:
        master:
          url: jdbc:mysql://127.0.0.1:3306/seata_sample_nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&nullCatalogMeansCurrent=true
          username: root
          password: 123456
          type: com.zaxxer.hikari.HikariDataSource

Druid不是一般的烂!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/880049.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号