session和threadLocal的使用(redis 2025.03.26学习记录)

85 阅读3分钟

session的使用

客户端首次向服务器发送请求,服务器会检查是否包含有效的session ID 没有则会新创建一个session对象,并分配一个唯一的session id

这个id会通过cookie或者url重写(即将session id附加到url后面)的方式返回给客户端

后续客户端发送请求都会将这个id发送给服务端,服务端再根据这个session id来查找对应的httpsession对象。 如果找到了就用这个session。如果id无效,或者已过期,被销毁,即便客户端发送了session id,服务器也可能不会使用该session,而是重新创建等处理

登录 拦截器的设置



package com.hmdp.utils;

import com.hmdp.dto.UserDTO; import com.hmdp.entity.User; import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;

public class LoginInterceptor implements HandlerInterceptor { //实现HandlerInterceptor接口 //接口有三个方法,需要实现两个方法 //preHandle

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    //1.获取session
    HttpSession session = request.getSession();
    //2.获取session中的用户
    Object user = session.getAttribute("user");
    //3.判断用户是否存在
    if (user == null) {
        //4.不存在 拦截
        response.setStatus(401);
        return false;
    }

    //5.存在 保存用户信息到ThreadLocal
    UserHolder.saveUser((UserDTO) user); //TODO threadlocal这里存放用户信息有什么用
    //6.放行
    return true;
}

//afterHandle

@Override   //TODO这里的afterCompletion怎么是请求结束后就把用户移除了,那后面不是还要靠这个来证明当前那个用户处于登录状态吗
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    //移除用户
    UserHolder.removeUser();
}

}


问题一,threadlocal存储用户信息的作用是?
通常http的每次请求由一个独立的线程处理。
方便获取用户数据不用重复从session那里解析得到用户数据。
有线程隔离和便携访问的功能。
从 ThreadLocal 获取比反复查询Session更高效、更简洁。
💡 补充说明:
 
 Session  是服务端会话管理机制,存储的是全局用户状态(如登录态)。
 
 ThreadLocal  是请求级别的临时存储,仅用于在当前请求链中共享数据,与用户是否登录无关。


问题二,为什么在 afterCompletion 中移除用户?
防止数据污染,比如说一次请求结束后然后另外一个请求如果是同一个线程,那么它的数据仍然保存着上一次请求用户的数据。
内存泄漏: ThreadLocal 中存储的对象会一直占用内存,直到线程销毁(而线程池中的线程可能长期存活)。
用户的登录状态不依赖 ThreadLocal 
 
用户的登录状态由 HttpSession 维护,只要Session未过期,用户依然处于登录状态。
 
每次新请求到达时, preHandle 方法会重新从Session中读取用户信息并存入 ThreadLocal ,因此移除操作不会影响用户登录状态。
 补充说明:
 
 afterCompletion  的触发时机:在视图渲染完成后执行(无论请求成功或异常),确保清理逻辑一定会执行。
 
与登录状态无关:用户的登录状态由  Session  维护, ThreadLocal  只是临时缓存,移除它不会影响用户是否已登录。