ThreadLocal的作用是在同一个线程共享数据,项目中每一个请求进来,从始至终都是同一个线程,在同一个线程中上一个线程放在内存中的数据如果要和下一个线程进行共享,那么就可以使用ThreadLocal
ThreadLocal的核心原理就是,它底层是一个Map<Thread,Object> threadLocal结构
/**
* 在执行目标方法前,先判断用户登录状态。并封装用户信息传递给Controller
*/
public class CartInterceptor implements HandlerInterceptor {
public static ThreadLocal<UserInfoTo> threadLocal = new ThreadLocal<>();
/*
目标方法之前拦截
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
UserInfoTo userInfoTo = new UserInfoTo();
HttpSession session = request.getSession();
MemberRespVo member = (MemberRespVo) session.getAttribute(AuthServerConstant.LOGIN_USER);
if (member != null) {
//用户登录
userInfoTo.setUserId(member.getId());
}
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
String name = cookie.getName();
if (name.equals(CartConstant.TEMP_USER_COOKIE_NAME)) {
userInfoTo.setUserKey(cookie.getValue());
userInfoTo.setTempUser(true);
}
}
}
//目标方法执行之前
//如果没有临时用户,分配临时用户
if (StringUtils.isEmpty(userInfoTo.getUserKey())) {
String uuid = UUID.randomUUID().toString();
userInfoTo.setUserKey(uuid);
}
threadLocal.set(userInfoTo);
return true;
}
/*
业务执行之后 分配临时用户
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
UserInfoTo userInfoTo = threadLocal.get();
//如果没有任何信息,创建临时用户,保存cookie
if (!userInfoTo.isTempUser()) {
Cookie cookie = new Cookie(CartConstant.TEMP_USER_COOKIE_NAME, userInfoTo.getUserKey());
cookie.setDomain("gulimall.com");
//单位秒
cookie.setMaxAge(CartConstant.TEMP_USER_COOKIE_TIMEOUT);
response.addCookie(cookie);
}
}
}