企业网站建设的目标,免费发布产品信息的网站,网络规划设计师多少分,做融资的网站有哪些Async和SpringSecurityContext
场景回溯
在执行一个用时较长的批量插入业务的时候,我尝试使用Async异步对业务进行优化,但是却给我报了空指针的错误,定位之后发现 此处我是基于SpringSecurity来获取用户的 是currentUserService获取到的当前登陆用户为空导致的,但是当前确实是…Async和SpringSecurityContext
场景回溯
在执行一个用时较长的批量插入业务的时候,我尝试使用Async异步对业务进行优化,但是却给我报了空指针的错误,定位之后发现 此处我是基于SpringSecurity来获取用户的 是currentUserService获取到的当前登陆用户为空导致的,但是当前确实是处于登陆状态的
然后,我删除了业务方法上的Async注解,这个方法执行了20s但是没有出现报错
由此可以确定是异步导致的错误
错误原因
SecurityContextHolder的底层默认是基于ThreadLocal的, 基于ThreadLocal就会导致异步执行的子线程拿不到主线程的ThreadLocal,从而导致SecurityContext中没有用户信息;
解决方式
既然子线程没有拿到父线程的ThreadLocal那就让他拿到不就好了,那我们该如何拿到呢?
InheritableThreadLocal是Java中的一个类它提供了类似于ThreadLocal的功能但具有额外的特性。它允许在ThreadLocal中存储的值在创建子线程时被子线程继承。
那我们如何让SecurityContext底层使用InheritableThreadLocal呢?
SpringSecurity贴心的为我们设计了基于InheritableThreadLocal的SecurityContext策略
并且在SecurityContextHolder中已经给出了对应的配置项 我们只需要进行相应的配置即可 public static void main(String[] args) {SpringApplication.run(LabourServiceApplication.class,args);//配置基于InheritableThreadLocal的SecurityContextSecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);}