spring-session源码解读-4

简介: spring session的生命周期Session获取spring-session实现了HttpServletRequest的子类–SessionRepositoryRequestWrapper,由它覆盖getSession方法,将由web容器处理的逻辑接管过来。public HttpSession getSession(boolean create

spring session的生命周期

spring session生命周期

Session获取

spring-session实现了HttpServletRequest的子类–SessionRepositoryRequestWrapper,由它覆盖getSession方法,将由web容器处理的逻辑接管过来。

public HttpSession getSession(boolean create) {
            HttpSessionWrapper currentSession = getCurrentSession();
            if(currentSession != null) {
                return currentSession;
            }
            String requestedSessionId = getRequestedSessionId();
            if(requestedSessionId != null) {
                S session = sessionRepository.getSession(requestedSessionId);
                if(session != null) {
                    this.requestedSessionIdValid = true;
                    currentSession = new HttpSessionWrapper(session, getServletContext());
                    //从数据仓库提取出来的session状态不为new
                    currentSession.setNew(false);
                    setCurrentSession(currentSession);
                    return currentSession;
                }
            }
            if(!create) {
                return null;
            }
            S session = sessionRepository.createSession();
            currentSession = new HttpSessionWrapper(session, getServletContext());
            setCurrentSession(currentSession);
            return currentSession;
        }

session id存在的情况下,如果通过session id能找到持久化的session就直接返回,否则根据create是否为true决定是否新建一个Session。Session在后续的使用中会陆续更改,添加、删除或者修改属性值。从数据仓库中提取出来的session会默认修改lastAccessTime属性以避免session失效。

数据仓库中的持久化session也存在失效时间,消费端可以通过RedisHttpSessionConfiguration.setMaxInactiveIntervalInSeconds(long timemills)来设置,默认是1800秒。redis会定时清除过期数据。

spring-session的Session实现

Spring为了将Session与具体的协议分开,单独提炼出Session实体,再通过HttpSessionWrapper将session包装起来,从而扩展HttpSession.如果以后还需要支持另外一种应用协议,就只要增加一种应用类型的wrapper就行了。

private final class HttpSessionWrapper implements HttpSession {

            public HttpSessionWrapper(S session, ServletContext servletContext) {
                this.session = session;
                this.servletContext = servletContext;
            }
            //省略了大部分方法,都是委托给被包装的Session处理的

            //对session坐invalidate时去数据仓库删掉对应的数据
            public void invalidate() {
                checkState();
                this.invalidated = true;
                requestedSessionInvalidated = true;
                setCurrentSession(null);
                sessionRepository.delete(getId());
            }

            public void setNew(boolean isNew) {
                this.old = !isNew;
            }

            public boolean isNew() {
                checkState();
                return !old;
            }
        }
    }

Session实体主要定义通用的getAttribute和setAttribute等方法。此外扩展了一个ExpiringSession,这是spring的默认session,它主要用来判断session是否失效。

public interface ExpiringSession extends Session {


    //session的创建时间
    long getCreationTime();


    //session的上次访问时间
    long getLastAccessedTime();


    //设置最大访问间隔,超过这个间隔session会被invalidate
    void setMaxInactiveIntervalInSeconds(int interval);

    int getMaxInactiveIntervalInSeconds();


    //session是否失效
    boolean isExpired();

}

session提交

        private void commitSession() {
            HttpSessionWrapper wrappedSession = getCurrentSession();
            if(wrappedSession == null) {
                if(isInvalidateClientSession()) {
                    httpSessionStrategy.onInvalidateSession(this, response);
                }
            } else {
                S session = wrappedSession.session;
                sessionRepository.save(session);
                if(!isRequestedSessionIdValid() || !session.getId().equals(getRequestedSessionId())) {
                    httpSessionStrategy.onNewSession(session, this, response);
                }
            }
        }
  1. getSession时会通过setCurrentSession把新建或者提取出来的session放到request的HttpServletRequestWrapper.class.getName()属性上;相应的在session invalidate时也会将session从request里移除掉,此时通过getCurrentSession将取不到数据。
  2. 在做session持久化时,会首先判断session是否被invalidate,如果是则会删除
目录
相关文章
|
3月前
|
小程序 数据可视化 Java
Java+后端Spring boot 开发的全套UWB定位方案,0.1米高精度定位系统源码
UWB定位系统由硬件定位设备、定位引擎和应用软件组成。该定位系统应用软件支持PC端和移动端访问,并提供位置实时显示、历史轨迹回放、人员考勤、电子围栏、行为分析、智能巡检等功能。定位精度高达10cm,同时具备高动态、高容量、低功耗的优点。应用场景包括:隧道、化工、工厂、煤矿、工地、电厂、养老、展馆、整车、机房、机场等。
70 8
|
3月前
|
XML Java 数据格式
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
74 3
|
3月前
|
存储 Java 程序员
Spring 注册BeanPostProcessor 源码阅读
Spring 注册BeanPostProcessor 源码阅读
|
3天前
|
人工智能 前端开发 Java
【实操】Spring Cloud Alibaba AI,阿里AI这不得玩一下(含前后端源码)
本文介绍了如何使用 **Spring Cloud Alibaba AI** 构建基于 Spring Boot 和 uni-app 的聊天机器人应用。主要内容包括:Spring Cloud Alibaba AI 的概念与功能,使用前的准备工作(如 JDK 17+、Spring Boot 3.0+ 及通义 API-KEY),详细实操步骤(涵盖前后端开发工具、组件选择、功能分析及关键代码示例)。最终展示了如何成功实现具备基本聊天功能的 AI 应用,帮助读者快速搭建智能聊天系统并探索更多高级功能。
29 2
【实操】Spring Cloud Alibaba AI,阿里AI这不得玩一下(含前后端源码)
|
2月前
|
Java Spring 容器
Spring Boot 启动源码解析结合Spring Bean生命周期分析
Spring Boot 启动源码解析结合Spring Bean生命周期分析
67 11
|
9天前
|
设计模式 Java 程序员
学习 Spring 源码的意义是什么呢?
研究Spring源码能深化框架理解,提升代码分析与设计能力,助您掌握设计模式及最佳实践,增强解决问题的效率,促进职业生涯发展,并激发技术热情。选择稳定版本,从核心模块开始,结合实际项目并参与社区,让学习之旅既充实又具乐趣。
|
2月前
|
缓存 Java 程序员
spring IoC 源码
spring IoC 源码
44 3
|
2月前
|
JavaScript Java 数据安全/隐私保护
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码(2)
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码
57 0
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码(2)
|
3月前
|
Java Spring 容器
解读spring5源码中实例化单例bean的调用链
解读spring5源码中实例化单例bean的调用链
|
3月前
|
Java Spring 容器
Spring源码学习——(一)
第一讲——了解BeanFactory和ApplicationContext
52 11
下一篇
云函数