ThreadLocal 是 Java 中的一个类,用于在每个线程中维护一个独立的、与该线程绑定的局部变量副本。这使得每个线程都可以拥有自己的变量实例,而不会与其他线程的实例相互干扰。ThreadLocal 不是存储单个值,而是为每个线程创建一个单独的存储空间,每个线程可以在这个空间中存取自己的值。
在web应用中使用存放数据
创建工具类使用
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存放
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断当前拦截到的是Controller的方法还是其他资源
if (!(handler instanceof HandlerMethod)) {
//当前拦截到的不是动态方法,直接放行
return true;
}
//1、从请求头中获取令牌
String token = request.getHeader(jwtProperties.getAdminTokenName());
//2、校验令牌
try {
log.info("jwt校验:{}", token);
Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
log.info("当前员工id:", empId);
//将员工id放入当前线程中
BaseContext.setCurrentId(empId);
//3、通过,放行
return true;
} catch (Exception ex) {
//4、不通过,响应401状态码
response.setStatus(401);
return false;
}
}
在service层获取员工id
public void save(EmployeeDTO employeeDTO) {
// 创建一个新的Employee实例,用于存储从DTO转换过来的员工信息
Employee employee = new Employee();
// 使用BeanUtils工具类将DTO对象的属性值复制到Employee对象中
BeanUtils.copyProperties(employeeDTO, employee);
// 设置员工密码为默认密码,并通过MD5加密
employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
// 设置员工状态为启用
employee.setStatus(StatusConstant.ENABLE);
// 设置员工的创建时间和更新时间为当前时间
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
// 从当前登录的用户中获取用户ID
employee.setCreateUser(BaseContext.getCurrentId());
employee.setUpdateUser(BaseContext.getCurrentId());
employeeMapper.insert(employee);
}