技术背景:
spring boot+mybatis-plus做公共字段填充(metaObjectHandler),之前项目没有接入用户系统故用户名填充都是使用的默认值,最近公司整合统一网关,接入用户信息,单例模式使用
ThreadLocal
但是测试组细心的小姐姐发现有一个接口调用的过程中发生用户名被还原成默认值的情况,一开始还不信。仔细观察发现这个接口存入的用户最终都变成了默认用户名。
抓鸡。。。。。。。
为什么呢,debug发现整个流程没问题啊,出问题也只有可能自动填这里充出问题了,断点进去果然发现这个接口的实现方法进来后threadLocal变成了null,其他方法进来都是正常的,怎么会出现这种情况呢,怀疑人生中。。。。。。
突然眼前一亮发现有猫腻,这个方法是异步实现的@Async,当初因为这个方法后台执行比较耗时,所以采用异步的方式,而spring boot中使用@Async是通过线程池,想到这里就不奇怪了 这就涉及到主线程和子线程数据共享的问题了,刚好之前了解过,赶紧把ThreadLocal的实现换一下inheritableThreadLocals测试一波,呵呵果然。



