通过ThreadLocal记录上下文信息(记录用户信息实现全局操作)

导读:本篇文章讲解 通过ThreadLocal记录上下文信息(记录用户信息实现全局操作),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

ThreadLocal为每一个线程都提供了变量的副本,并且变量在整个线程的生命周期有效,形成了线程与线程之间的隔离,只有同一个线程才能操作变量,是一种”以空间换时间”的形式,可以用来记录一些上下文数据。

ThreadLocal内部通过Map来储存每一个线程的变量副本,map的key就是threadLocal,value就是我们set的那个值,每次线程在get的时候,都从自己的变量中取值,所以肯定就不存在线程安全问题。
使用ThreadLocal后,一定要注意手动remove()否则会造成OOM异常。

场景如下:

  • 记录每次请求用户信息

ThreadLocal代码:

public class RequestHolder {

    private static final ThreadLocal<SysUser> userHolder = new ThreadLocal<SysUser>();


    public static void setUser(SysUser sysUser) {
        userHolder.set(sysUser);
    }

    public static SysUser getUser() {
        return userHolder.get();
    }

    public static void remove() {
        userHolder.remove();
    }
}

应用流程:
以下流程部分使用伪代码表示
1、拦截器获取用户信息
2、记录到ThreadLocal中
3、使用时通过get()方法获取值

// 1、拦截器获取用户信息
// 2、记录到ThreadLocal中
@Component
public class AuthenticationHandlerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.debug("进入拦截器,URL:{}", request.getServletPath());

        // 加入用户全局信息
        RequestHolder.setUser(userInfo);
        return true;
    }
    ....
    ....
}

// 3、使用时通过get()方法获取值
@RestController
@RequestMapping
public class Controller {
   .....
    @GetMapping("/test")
    public String test() {
    	// 从ThreadLocal获取数据
    	RequestHolder.getUserId();
        return "访问成功";
    }
   .....
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/18063.html

(0)
小半的头像小半

相关推荐

极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!