关于Sharding-JDBC数据源配置有下划线报错的问题

前言

这里是继上文中,关于数据源配置了下划线之后读取不到的问题的探究。再上篇文章中我在文章里强调了这个问题,网上说的模棱两可。官方文档也未作出详细说明,所以自己花了点时间,进行调试略有心得,在这里分享!

前文

《Sharding-JDBC简单使用》
《Sharding-JDBC主子表(绑定表)关联》
《Sharding-JDBC读写分离配置》

故障重现

我在配置文件里,给数据源名称设置了下划线,然后报错
在这里插入图片描述
在这里插入图片描述
根据代码调试原则,哪里能点点哪里。

调试之旅

我们看这里,是放置数据源的地方org.apache.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration.setEnvironment
在这里插入图片描述
Map<String, Object> dataSourceProps = (Map)PropertyUtil.handle(environment, prefix + dataSourceName.trim(), Map.class);

这行代码往下就报错,说明问题就是从这里抛出来的进去!!!
调试代码就是要一点点重来一点点进(谁让我菜,我只能这样,你要是有走读代码的能力,自然更好!)

在这里插入图片描述
springboot1.x走v1,springboot2.x走v2,这里并不是重点
在这里插入图片描述

    @SneakyThrows
    private static Object v2(final Environment environment, final String prefix, final Class<?> targetClass) {
        Class<?> binderClass = Class.forName("org.springframework.boot.context.properties.bind.Binder");
        Method getMethod = binderClass.getDeclaredMethod("get", Environment.class);
        Method bindMethod = binderClass.getDeclaredMethod("bind", String.class, Class.class);
        Object binderObject = getMethod.invoke(null, environment);
        String prefixParam = prefix.endsWith(".") ? prefix.substring(0, prefix.length() - 1) : prefix;
        //这里是关键,你看他究竟反射调用哪个方法!
        Object bindResultObject = bindMethod.invoke(binderObject, prefixParam, targetClass);
        Method resultGetMethod = bindResultObject.getClass().getDeclaredMethod("get");
        return resultGetMethod.invoke(bindResultObject);
    }

他这里反射调用了binder

binder里的bind方法有很多重载,不过都不重要,因为他根本进行不下去,说明在进去的那个方法就报错所以说细看

this.bind((ConfigurationPropertyName)ConfigurationPropertyName.of(name), target, (BindHandler)null);

进入ConfigurationPropertyName.of(name)
在这里插入图片描述
一路进入到这里
在这里插入图片描述
直接看这里

Elements elements = (new ElementsParser(name, ‘.’, parserCapacity)).parse();

for(int i = 0; i < length; ++i) {
                char ch = this.source.charAt(i);
                if (ch == '[') {
                    if (openBracketCount == 0) {
                        this.add(start, i, type, valueProcessor);
                        start = i + 1;
                        type = ConfigurationPropertyName.ElementType.NUMERICALLY_INDEXED;
                    }

                    ++openBracketCount;
                } else if (ch == ']') {
                    --openBracketCount;
                    if (openBracketCount == 0) {
                        this.add(start, i, type, valueProcessor);
                        start = i + 1;
                        type = ConfigurationPropertyName.ElementType.EMPTY;
                    }
                } else if (!type.isIndexed() && ch == this.separator) {
                    this.add(start, i, type, valueProcessor);
                    start = i + 1;
                    type = ConfigurationPropertyName.ElementType.EMPTY;
                } else {
                    type = this.updateType(type, ch, i - start);
                }
            }

直接把遍历的下标条件设置成35,方便自己一直调试
https://blog.csdn.net/weixin_43953546/article/details/102807792 左击打断点,右击输入条件
在这里插入图片描述

这里我们能看到他是在遍历spring.shardingsphere.datasource.ds0_master这个字符串,到这里我们大概能猜到了,可能是这个_ , 这里属于非法字符串(猜对了)

在这里插入图片描述
断点进入到isValidChar这个方法!
在这里插入图片描述
其实到这里,看名字我们都能猜到并证实自己猜想了
在这里插入图片描述

必须是a-z 或则 0-9或者-,其余都是非法字符串!!

反证

取消下划线,使用大写M,执行,果然报错!
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值