场景:
一个后台管理系统,当前登录用户(user1)在修改其他某个用户(user2)信息后,需要在数据库中将被修改用户(user2)的修改人信息填写为当前用户(user1)的id
解决办法:
前端发送请求执行过程:
- 用户登录成功后,后端会生成一个JWT-Token返回给前端;
- 之后前端每次给后端发送请求都会在请求头中携带该JWT-Token,后端拦截器会拦截这次请求,在验证JWT-Token正确后才会允许这次请求(验证不通过会返回错误信息,前端会自动跳转到登陆页面)
思路:
根据上述执行过程,我们可以得到如下思路:
- 首先我们可以把登录用户的id封装到JWT-Token中去,前端每次操作时都可以从JWT-Token中获得其id
(但由于拦截并解析JWT-Token是拦截器所做的,从而只能在拦截器中获取到id,怎么将此id信息传递给之后的controller、service层呢?于是便有了第2步) - 然后使用ThreadLocal工具类,将用户的id等信息存储到ThreadLocal对象中
- 之后的控制层、业务处理层直接调用ThraedLocal对象就可以获取到当前用户的id等信息
解释:
ThreadLocal并不是一个线程,而是当前线程的局部变量。
ThreadLocal为每个线程单独提供一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。
(客户端发送的每次请求,Spring后端内嵌的Tomcat服务器都会分配一个单独的线程来处理,于是每次请求的当前用户信息都可以通过ThreadLocal存储在对应的线程内部)
ThreadLocal的常用方法:
方法名 | 作用 |
---|---|
public void set(T value) | 设置当前线程的线程局部变量的值 |
public void get() | 返回当前线程所对应的线程局部变量的值 |
public void remove() | 移除当前线程的线程局部变量 |