起因
六月六日夜,解衣欲睡,网友求助让帮忙运行一下自己在Github下载的源码,说是一个SpringBoot的系统,怎么都发动不起来,我心想这不张飞吃豆芽-小菜一碟吗?可是便是这么简略的工作,让我琢磨了近两个小时。最后我总结出是00后程序员用SpringBoot有Bug,斜眼笑,且看下文。
还原现场
先看网友的application.yaml
截图,打眼一看,没什么问题,仔细看仍是没什么问题。但发动项目报错,提示连接数据库暗码过错。
开端测验处理
首要用命令行登录mysql,验证下本地是否有装mysql,且账号暗码是否正确,再验证下链接中的数据库是否存在(虽然没有数据库报的不是这个错)。
结果是:都没有问题。
然后,没办法直接持续看报错日志,发现日志中说jdbcDialect
Bean创建失利,点进去打上断点看看吧。
再发动项目,断点停住了,然后开端查看operations
目标的属性,通过一顿乱翻,发现了在operations
-> classicJdbcTemplate
-> dataSource
下存在数据库连接信息。翻开一看傻眼了。
账号、驱动、链接都对,怎么你暗码变成8533
了,我明明装备的是020525
啊,为什么?
刚开端我怀疑难道在其他地方装备了数据库信息,没有加载application.yaml
中的?可是我全局查找了8533
,无果。然后测验修正账号为root1
,再debug发动。
发现账号成功加载到了root1,那阐明数据库连接信息便是加载的application.yaml
中装备的。那这是为啥呢,小小的脑袋,大大的问号!
随后又测验修正application.yaml
文件,由于这个源码运用的是默认的数据库连接池,所以测验装备连接池的暗码为020525
,可是debug发动之后,仍是显现8533
!!,这时我快疯了。
可是不能抛弃,究竟刚开端可是怀着小菜一碟的心态来的。又开端删刚加的hikari.password
装备,再把之前的password
还原。习气运用快捷键的我,再username
这一行,运用ctrl + D仿制当前行,便是下面这个样子,然后我把下面的username
改成password
,这是已经不想把password
的值改回到020525
了,由于已经快崩溃了!其实当你测验了所有失利的可能之后,你就只剩下了成功!
再debug发动看看,再看dataSource
中加载的数据库装备信息,惊奇的发现,暗码加载的是root1,可真是山重水复疑无路,柳暗花明又一村啊。
这下就开端想root1
和020525
两个暗码的差异,首要一个是纯数字,一个是字母+数字。难道是SpringBoot
某个版别的bug,会将数字暗码转义掉?但很快排除了这个问题,由于国人在装置MySQL时暗码不是123456
,便是root
,所以纯数字肯定是没有问题的,也修正暗码为123456
进行了验证,也的确没有问题。
到这,其实大多人就停步于此,究竟能跑就行,我也是,帮网友修正了数据库root暗码,改为root,再修正application.yaml
中的暗码,再次发动,不出意外,成功发动。关机!睡觉!
可是刚躺倒到床上,心里一向想这个工作,020525
和123456
有啥差异呢(彩蛋:这网友肯定是个00后,而且是5月25的,所以00后用SpringBoot
有Bug)。
不睡了,睡什么睡,然后又起床开电脑,预备弄清楚为什么020525
加载到datasource
里面会变成8533
,然后从刚开端打断点的地方往上找,找了很久没一点条理,人在晚上脑子是真的转不过来。最后才想到,可以从加载application.yaml
开端往下找啊,看到底是哪里把020525
改成了8533
,于此同时也查找了相关SpringBoot
加载application.yaml
的相关文档,这里找到一篇18张图,详解SpringBoot解析yml全流程,发现他的情况和我的相似,可是我看源码功底真的太差劲了,跟着他的路径找,终究发现了奥妙之处。
其实便是在解析application.yaml
中的装备文件时,SpringBoot引入的是org.yaml:snakeyaml包,当你装备value榜首个字符是yaml中规矩的特殊字符之后,然后再用特殊字符中所对应的正则表达式进行校验,假如校验不通过,则认为是字符串;假如校验通过,则就会对这个value进行转化了,而咱们刚好巧的是,咱们的暗码榜首位是0
,所以咱们满意了其间一个规矩。
持续跟源码,发现,进入了ConstructYamlInt
的construct
方法,具体规矩如下。
由于咱们的暗码是020525
,榜首个字符是0
,所以被认为咱们传入的值是8进制,然后截掉榜首位,剩下5位,为20525
,后面createNumber便是将八进制20525
转为十进制,此时这个020525
就加载完成了。
所以就解说了为啥020525
变成了终究的8533
。
总结
这个问题的原因便是咱们数据库暗码是以0最初的,所以被yaml解析器过错的认为咱们的value是8进制的,它帮咱们转化成了10进制,所以一向导致数据库暗码过错,连接失利。
处理方案呢,最简略的便是在application.yaml
装备纯数字时,一定要小心,防止0、0b、0x最初,假如非要用,那么一定要在value前后加上单引号,这样yaml解析器就不会帮咱们转化进制了。
附录列举了yaml会匹配的榜首个字符列表。
附录
参考资料
18张图,详解SpringBoot解析yml全流程