【已解决】Spring Security中,多线程操作导致上下文丢失

一 、问题

某个功能因涉及的表比较多,想改成多线程异步操作。

但是在功能实现过程中,问题出来了

在登入完成后项目在请求中封装了HospitalId在请求域中,然后继承项目封装好的BaseService可以在Service层直接调用this.getHospitalId()获取值

当开启多线程的时候this.getHospitalId()会报错 空指针异常

正常操作是

//开启线程前获取请求
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//每一个线程都来共享之前的请求数据
RequestContextHolder.setRequestAttributes(requestAttributes);

但这样还是会空指针

二、解决方法

使用了Spring Security获取的请求就变了

//在主线程中获取安全上下文
SecurityContext securityContext = SecurityContextHolder.getContext();
//将主线程中的安全上下文设置到子线程中的ThreadLocal中
SecurityContextHolder.setContext(securityContext);
// 清除操作
// 将调用者中的安全上下文设置到当前业务子线程中的ThreadLocal中。
SecurityContextHolder.clearContext();

第三步的清除操作必不可少,不然会导致异步线程的安全上下文传播到线程池中,而如果该线程为线程池的核心线程,下次该线程执行时又没有设置安全上下文,则会获取到错误的信息(也就是这次设置的安全上下文信息)

三、原因

因为Spring Security的安全上下文默认是存储在ThreadLocal(也就是线程本地)的,启动其他线程执行的时候,就会丢失掉上下文信息。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值