ThreadLocal在线程池环境下使用(SpringBoot)

ThreadLocal在线程池环境下使用(SpringBoot)

ThreadLocal的问题

当今项目,大多数都会使用线程池的,而ThreadLocal是基于线程的,这就有一个问题,如果ThreadLocal没有及时清理的话,碰到线程被复用的时候,就可以获取到上一次请求的数据。
关于这个问题,网上其实有很多解决方案,但是都是要手动清理ThreadLocal,这个清理的时机,就是一个问题,在什么时候清,如果方法里用完就清,你能保证其他方法就不用了吗?而且手动清理总有不小心漏掉的情况。

解决方案

其实可以通过对ThreadLocal进行一个小小的封装,就可以解决这个问题。

  1. TheadLocal不要作为业务类的成员变量,新建一个Util,对其进行统一管理。
public class ThreadLocalUtils {
    private static final ThreadLocal<Map<String,Object>> threadCache = new ThreadLocal<>();

    private static void init(){
        Map<String,Object> map = new HashMap<>();
        threadCache.set(map);
    }
    public static void setThreadCache(String key, Object value){
        if(threadCache.get() == null){
            init();
        }
        threadCache.get().put(key, value);
    }

    public static Object getThreadCache(String key){
        if(threadCache.get() == null){
            init();
        }
        return threadCache.get().get(key);
    }

    public static void removeThreadCache(){
        threadCache.remove();
    }
}
  1. 通过切面来统一关闭TheadLocal
@Component
@Aspect
public class TheadLocalAspect {

    @After(
            "@annotation(org.springframework.web.bind.annotation.RequestMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.PostMapping)"
    )
    public void after(){
        ThreadLocalUtils.removeThreadCache();
    }
}

至于为什么选择after来处理,看下图:
在这里插入图片描述
After通知是在目标方法结束后,无论如何都会触发的,用其来清理ThreadLocal最为合适。

使用

使用方式如下(举了一些简单例子):

//保存用户。
ThreadLocalUtils.setThreadCache("USER", user);
//获取用户, 因为存储的是Object类型,所以需要强制类型转换。
User user = (User)ThreadLocalUtils.getThreadCache("USER");

因为ThreadLocalUtils的threadCache会由切面统一清理,所以使用时不必清理。

结尾

切面只拦截了Http请求的,所以这个工具类也只适用于Http请求的ThreadLocal管理,但是目前来说SpingBoot架构的互联网业务场景绝大多数是基于Http的,REST请求是Http、SpringCloud的微服务架构也是基于Http,物联网设备请求SpringBoot项目的后台,也是配置的Http。如果真的有非Http请求的情况,修改TheadLocalAspect类切点即可。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值