讲一下背景:springboot 项目。写了个拦截器,解析请求头 Authorization 中传过来的 token,获取到登录用户信息,然后通过 ThreadLocal 存起来,后面的业务代码从 ThreadLocal 取用户信息。
再说下问题:当业务代码被 @Async 标记的时候,从 ThreadLocal 就取不到用户信息了。
上面说的这个场景,包括取不到用户信息的原因,网上有大把,包括解决办法,也都有,这篇文章也只是做个记录。
- 第一种解决办法
用阿里巴巴开源的 TransmittableThreadLocal 替代 ThreadLocal
在拦截器中将用户信息保存起来,如下图
在业务代码中取用户信息,如下图
顺便看一下 @Async 用的线程池,如下图
这种方式是可以取到用户信息的,如下图
- 第二种解决办法
利用 spring 提供的 TaskDecorator
注意下图,用的是普通的 ThreadLocal
在拦截器中保存用户信息,如下图
在业务代码中获取用户信息,如下图
这里边的关键是 @Async 用到的线程池,如下图
这种方式也是可以的,看下执行结果,取到了用户信息,如下图
正文到这里其实就完了。下面再看个例子,本质还是上面讲的第二种解决办法。
注意,下图用的是普通的 ThreadLocal
在拦截器中保存用户信息,如下图
在业务代码中获取用户信息,如下图
这里边的关键点是 ThreadUtil 类中的 THREAD_POOL_TASK_EXECUTOR ,如下图
看下执行结果,取到了用户信息,如下图