利用threadLocal 把拦截器中的对象传递到controller或service中

1.可以用 request 携带数据。

2.更优雅的方式是用threadlocal。

请求进入tomcat 和产生响应前,都处于同一个线程中比如在一个登录拦截器中,在preHandle方法中登录成功后,放行前,想把user对象传到controller或service中,最后在拦截器的afterCompletion方法中移除。

创建一个类UserThreadLocal.java

public class UserThreadLocal {

    //把构造函数私有,外面不能new,只能通过下面两个方法操作
private UserThreadLocal(){ } private static final ThreadLocal<User> LOCAL = new ThreadLocal<User>(); public static void set(User user){
LOCAL.set(user);;
} public static User get(){
return LOCAL.get();
}
}

相当于一个容器,此容器伴随着线程,线程启动,就有这个容器,销毁,容器就跟着销毁。生命周期就是这个线程。

在拦截器中,登录成功后,放行前加上

 //登录成功

UserThreadLocal.set(user);//将user对象放置在本地线程中,方便controller和service获取

由于tomcat 的运行机制,要及时清空threadLocal的内容,以下可以放在拦截器的afterCompletion方法中

/*tomcat底层 每一个请求都是一个线程,如果每一个请求都启动一个线程,性能就会降低,
1. 于是就有了线程池,而线程池中的线程并不是真正销毁或真正启动的。
2. 也就是说这个请求的线程是个可复用的线程,第二次请求可能还会拿到刚刚的线程,
3. 若不清空,里面本身就有user对象,数据会错乱*/
UserThreadLocal.set(null); //清空本地线程中的user对象数据

在controller 或 service 中调用

  User user = UserThreadLocal.get();

实现ThreadLocal复制到新线程@Async

方法一:

如何在子线程和线程池中使用 ThreadLocal 传输上下文

方法二:

第一步:自定义Spring线程池

@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setTaskDecorator(new UserThreadLocalTaskDecorator());
executor.initialize();
return executor;
}

第二步:自定义TaskDecorator

/**
* @author kancy
* @version 1.0
* @date 2019/4/24 11:01
*/
public class UserThreadLocalTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
// 从当前线程中获取user
User user = UserThreadLocal.get();
Runnable newRunnable = new Runnable(){
@Override
public void run() {
try{
// 放到新线程中
UserThreadLocal.set(user);
runnable.run();
}finally {
UserThreadLocal.set(null);
}
}
};
return newRunnable;
}
}

参考:

https://github.com/moelholm/smallexamples/tree/master/spring43-async-taskdecorator

https://moelholm.com/2017/07/24/spring-4-3-using-a-taskdecorator-to-copy-mdc-data-to-async-threads/

http://www.sohu.com/a/280604362_100270933

ThreadLocal 应用的更多相关文章

  1. ThreadLocal简单理解

    在java开源项目的代码中看到一个类里ThreadLocal的属性: private static ThreadLocal<Boolean> clientMode = new Thread ...

  2. Android线程管理之ThreadLocal理解及应用场景

    前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...

  3. Threadlocal使用Case

    Threadlocal能够为每个线程分配一份单独的副本,使的线程与线程之间能够独立的访问各自副本.Threadlocal 内部维护一个Map,key为线程的名字,value为对应操作的副本. /** ...

  4. 多线程映射工具——ThreadLocal

    ThreadLocal相当于一个Map<Thread, T>,各线程使用自己的线程对象Thread.currentThread()作为键存取数据,但ThreadLocal实际上是一个包装了 ...

  5. ThreadLocal 工作原理、部分源码分析

    1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap t ...

  6. ThreadLocal<T>的是否有设计问题

    一.吐槽 ThreadLocal<T>明显是.NET从JAVA中来的一个概念,但是这种设计是否出现了问题. 很明显,在JAVA中threadLocal直接是Thread的成员,当然随着th ...

  7. 理解ThreadLocal —— 一个map的key

    作用: 当工作于多线程中的对象使用ThreadLocal维护变量时,threadLocal为每个使用该变量的线程分配一个独立的变量副本. 接口方法: protected T initialValue( ...

  8. JavaSe:ThreadLocal

    JDK中有一个ThreadLocal类,使用很方便,但是却很容易出现问题.究其原因, 就是对ThreadLocal理解不到位.最近项目中,出现了内存泄漏的问题.其中就有同事在使用ThreadLocal ...

  9. 0041 Java学习笔记-多线程-线程池、ForkJoinPool、ThreadLocal

    什么是线程池 创建线程,因为涉及到跟操作系统交互,比较耗费资源.如果要创建大量的线程,而每个线程的生存期又很短,这时候就应该使用线程池了,就像数据库的连接池一样,预先开启一定数量的线程,有任务了就将任 ...

  10. ThreadLocal 源码剖析

    ThreadLocal是Java语言提供的用于支持线程局部变量的类.所谓的线程局部变量,就是仅仅只能被本线程访问,不能在线程之间进行共享访问的变量(每个线程一个拷贝).在各个Java web的各种框架 ...

随机推荐

  1. Linux新增用户,并设置Root(管理员)权限

    在使用Linux过程中,Root账号拥有最大的操作权限.为保证Root账号安全,一般不直接使用Root账号,而是直接创建一个拥有Root权限的其它账号来使用.详细操作步骤如下 第一步,创建用户,如下图 ...

  2. <<Effective Java>> 第四十三条

    <<Effective Java>> 第四十三条:返回零长度的数组或者集合,而不是null 如果一个方法的返回值类型是集合或者数组 ,如果在方法内部需要返回的集合或者数组是零长 ...

  3. CSS - 视觉格式化模型(Visual formatting model)

    几个概念 块:block,一个抽象的概念,块与块之间在垂直方向上按照顺序依次堆叠. 行内:inline,一个抽象的概念,行内与行内之间在水平方向上按照顺序依次堆叠(会有换行). 元素:element, ...

  4. Linux_NIS+NFS+Autofs

    目录 目录 前言 NIS NFS Autofs 搭建NISNFSAutofs Setup NNA environment Setup ServerSite Setup client 前言 NIS+NF ...

  5. 阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第4节 ArrayList集合_13-ArrayList集合概述和基本使用

    新建类 多了个尖括号,大写字母E,这是什么意思呢? 尖括号当中叫做泛型.存储的统一的类型,这个类型就在尖括号里面写上,我们用一个字母占位表示. 如何创建呢 构造方法有三个,最常用的就是无参构造 先掌握 ...

  6. eclipse 背景绿豆沙颜色

    General -> Editors -> Text Editors -> Appearance color options -> Background color 色调:85 ...

  7. MVC 源码系列之路由(一)

    路由系统 注释:这部分的源码是通过Refector查看UrlRoutingModule的源码编写,这部分的代码没有写到MVC中,却是MVC的入口. 简单的说一下激活路由之前的一些操作.一开始是由MVC ...

  8. 腾讯重磅开源分布式NoSQL存储系统DCache

    当你在电商平台秒杀商品或者在社交网络刷热门话题的时候,可以很明显感受到当前网络数据流量的恐怖,几十万商品刚开抢,一秒都不到就售罄:哪个大明星出轨的消息一出现,瞬间阅读与转发次数可以达到上亿.作为终端用 ...

  9. 【BASIS系列】SAP 中查看account登陆次数及时间的情况

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[BASIS系列]SAP 中查看account登 ...

  10. github项目分享

    unity 项目合集:https://michidk.github.io/Unity-Script-Collection/ ugui特效:https://github.com/mob-sakai/UI ...