为什么我可以在拦截其中BaseContext.setCurrentId(empId);然后在controller中通过BaseContext.getCurrentId(empId);拿到值

系列博客目录



1.为什么我可以在拦截其中BaseContext.setCurrentId(empId);然后在controller中通过BaseContext.getCurrentId(empId);拿到值。

你能够在拦截器中调用 BaseContext.setCurrentId(empId),并在控制器中通过 BaseContext.getCurrentId() 拿到值,是因为 ThreadLocal 的作用。ThreadLocal 可以让你在同一个线程内跨方法传递数据,而这些数据是线程独立的。

主要原因是 ThreadLocal 如何工作

1. ThreadLocal 是基于线程的

ThreadLocal 会为每个线程维护一份独立的变量副本。当你在拦截器中调用 BaseContext.setCurrentId(empId) 时,数据会存储在当前请求的线程的 ThreadLocal 存储中。同一请求线程中后续所有的方法调用都可以访问到这份存储。

  • 在拦截器中调用 BaseContext.setCurrentId(empId),将 empId 设置到当前线程的 ThreadLocal 存储中。
  • 在控制器中调用 BaseContext.getCurrentId(),可以从当前线程的 ThreadLocal 中获取先前存储的数据(即 empId)。

2. 请求线程的独立性

当 Web 应用处理一个 HTTP 请求时,通常每个请求都会在一个独立的线程中执行。因此,所有在同一线程内执行的操作(例如拦截器和控制器中的方法)都可以共享同一个 ThreadLocal 变量的数据。

  • 在拦截器中设置 BaseContext.setCurrentId(empId) 时,empId 会被保存在当前请求所使用的线程中的 ThreadLocal 变量里。
  • 当请求到达控制器时,同一线程仍然在执行,所以控制器可以通过 BaseContext.getCurrentId() 获取到相同的 empId

工作过程:

  1. 拦截器阶段

    • 在请求的拦截器中,你调用了 BaseContext.setCurrentId(empId),此时 empId 被保存在当前请求线程的 ThreadLocal 存储中。
    public class MyInterceptor implements HandlerInterceptor {
         
         
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         
         
            Long empId = getEmpIdFromRequest(request);
            BaseContext.setCurrentId(empId);  // 将 empId 设置到当前线程的 ThreadLocal 中
            return true;
        }
    }
    
  2. 控制器阶段

    • 在控制器中,通过 BaseContext.getCurrentId() 获取当前线程的 ThreadLocal 中的 empId,因为该线程中存储了拦截器中设置的数据。
    @RestController
    public class MyController {
         
         
        @GetMapping(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值