TransmittableThreadLocal

2024-08-24 08:44

本文主要是介绍TransmittableThreadLocal,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

为了防止提交表单的时候携带的个人信息被篡改,我们经常使用token保存用户的个人信息,每次调用都是传token解析出个人信息,保存在当前的线程中,在哪里使用了我们就在线程中取出,防止提交人和个人信息不一致。

在使用线程池上下文存取用户信息在 当前线程中接口登录的时候获取token 解析token信息 将用户信息添加TransmittableThreadLocal的实例中,防止提交的用户信息被篡改。在接口中使用到用户信息的时候可以在上下文中取出,当前线程使用结束需求清除掉。清除的原因防止添加多次内存一直占用,如果遇到使用相同线程的业务会取到其他人存入的用户信息。比如我目前用到定时任务用的@Schedule,他实现的使用的相同的线程,当前一个任务结束用户信息添加了没有删除,下一个任务获取的就是上个任务的用户信息,坑惨了。

TransmittableThreadLocal 优势在于主线程中设置的值在子线程中可以获取到,需要注意对线程中使用后需要回收。

工具类

public class UserContext {private static final TransmittableThreadLocal<Map<String, Object>> threadLocal=new TransmittableThreadLocal<>();/*** 创建实例** @return*/public static UserContext getInstance() {return SingletonHolder.sInstance;}/*** 静态内部类单例模式* 单例初使化*/private static class SingletonHolder {private static final UserContext sInstance = new UserContext();}/*** 用户上下文中放入信息** @param map*/public void setContext(Map<String, Object> map) {threadLocal.set(map);}/*** 获取上下文中的信息** @return*/public Map<String, Object> getContext() {return threadLocal.get();}/*** 获取上下文中的用户名** @return*/public String getUsername() {return Optional.ofNullable(threadLocal.get()).orElse(Maps.newHashMap()).get("account").toString();}public String getRoleId(){return Optional.ofNullable(threadLocal.get()).orElse(Maps.newHashMap()).get("roleId").toString();}public String getUserId(){return Optional.ofNullable(threadLocal.get()).orElse(Maps.newHashMap()).get("id").toString();}public Long getUserIdLong(){return Long.valueOf(Optional.ofNullable(threadLocal.get()).orElse(Maps.newHashMap()).get("id").toString());}/*** 清空上下文*/public void clear() {threadLocal.remove();}}

拦截每个请求 添加上下文 使用完成就需要清掉

@Slf4j
public class UserInterceptor implements HandlerInterceptor {private static final String USER = "user";@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 获取用户IDString str=request.getHeader(USER);if (StringUtils.isBlank(str)){return true;}UserDetail userDetail = JSON.parseObject(str, UserDetail.class);UserContext.getInstance().setContext(new ObjectMapper().readValue(str,Map.class));return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
//        Thread.sleep(300000);UserContext.getInstance().clear();}

接口中使用

 UserContext.getInstance().getUserId()

这篇关于TransmittableThreadLocal的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1102001

相关文章

线程间数据传递之ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal

线程间数据传递之ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal 1、ThreadLocal介绍 spring 中基于 ThreadLocal 来实现事务。 多线程 访问同一个共享变量的时候容易出现并发问题,ThreadLocal是除了加锁这种同步方式之外的一种保证 规避多线程访问出现线程不安全的方法,当我们在创建一个变

【多线程开发 2】从代码到实战TransmittableThreadLocal

【多线程开发 2】从代码到实战TransmittableThreadLocal 本文将从以下几个点讲解TransmittableThreadLocal(为了方便写以下简称ttl): 前身 是什么? 可以用来做什么? 源码原理 实战 前身 ThreadLocal 要了解ttl就要先了解Java自带的类ThreadLocal,threadlocal是作为当前线程中属性Thread

TransmittableThreadLocal 测试

主要解决了两个问题 1. thradlocal传入线程池 2. 线程池内的线程脏读 (读取了上一个threadlocal保存的值) 下方是测试代码 package org.dromara.web;import com.alibaba.ttl.TransmittableThreadLocal;import com.alibaba.ttl.threadpool.TtlExecutors;

阿里 TransmittableThreadLocal 解决 线程池模式下,线程间变量传递的问题

为什么用 因为jdk中的ThreadLocal,InheritableThreadLocal 无法在父子线程,父线程与线程池之间变量的传递关键代码 private static TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();// 创建一个固定大小的线程池,实际中肯定不这样建,demo

TransmittableThreadLocal 问题杂记

0、前言   TransmittableThreadLocal,简称 TTL,是阿里巴巴开源的一个Java库,它能够实现ThreadLocal在多线程间的值传递,适用于使用线程池、异步调用等需要线程切换的场景,解决了ThreadLocal在使用父子线程、线程池时不能正确传递值的问题。核心实现:捕获(capture)- 重放(replay)- 恢复(restore) 捕获:将父线程的 TTL/T

TransmittableThreadLocal-可在父子线程中传递变量

ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal的区分及原理: 推荐博文: Java 学习笔记(三)之 ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal 作者结论总结: 1) ThreadLocal 用来存储线程本地变量,仅是线程自己存储数据的,

TransmittableThreadLocal (TTL)

官方文档 问题描述 在日常的开发中,我们经常会通过多线程来提高业务执行效率,例如: 当前登录用户信息放在ThreadLocal内,然后service在处理业务逻辑时通过线程池来异步的处理,由于线程池内的线程与当前主线程不是同一个,因此获取不到主线程存放的用户信息 Runnable runnable = ()->{while(true){//处理用户数据-会从ThreadLoca内获取

有了InheritableThreadLocal为啥还需要TransmittableThreadLocal?

有了InheritableThreadLocal为啥还需要TransmittableThreadLocal? 典型回答 InheritableThreadLocal是用于主子线程之间参数传递的,但是,这种方式有一个问题,那就是必须要是在主线程中手动创建的子线程才可以,而现在池化技术非常普遍了,很多时候线程都是通过线程池进行创建和复用的,这时候InheritableThreadLocal就