介绍
ThreadLocal 并不是一个Thread,而是Thread的局部变量。
ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。
常用方法
- public void set(T value) 设置当前线程的线程局部变量的值
- public T get() 返回当前线程所对应的线程局部变量的值
- public void remove() 移除当前线程的线程局部变量
使用场景
在JavaWeb开发中,将从拦截器中解析到的当前登录用户ID传递给其他方法使用。
代码:
封装了 ThreadLocal 操作的工具类:
在sky-common模块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.sky.context;
public class BaseContext { public static ThreadLocal<Long> threadLocal = new ThreadLocal<>(); public static void setCurrentId(Long id) { threadLocal.set(id); } public static Long getCurrentId() { return threadLocal.get(); } public static void removeCurrentId() { threadLocal.remove(); } }
|
在拦截器中解析出当前登录员工id,并放入线程局部变量中:
在sky-server模块中,拦截器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.sky.interceptor;
@Component @Slf4j public class JwtTokenAdminInterceptor implements HandlerInterceptor {
@Autowired private JwtProperties jwtProperties;
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { try { Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token); Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString()); log.info("当前员工id:", empId); BaseContext.setCurrentId(empId); return true; } catch (Exception ex) { } } }
|
在Service中获取线程局部变量中的值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
public void save(EmployeeDTO employeeDTO) {
Long currentId = BaseContext.getCurrentId(); employee.setCreateUser(currentId); employee.setUpdateUser(currentId);
employeeMapper.insert(employee); }
|