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,如果是则会删除
目录
相关文章
|
6天前
|
小程序 数据可视化 Java
Java+后端Spring boot 开发的全套UWB定位方案,0.1米高精度定位系统源码
UWB定位系统由硬件定位设备、定位引擎和应用软件组成。该定位系统应用软件支持PC端和移动端访问,并提供位置实时显示、历史轨迹回放、人员考勤、电子围栏、行为分析、智能巡检等功能。定位精度高达10cm,同时具备高动态、高容量、低功耗的优点。应用场景包括:隧道、化工、工厂、煤矿、工地、电厂、养老、展馆、整车、机房、机场等。
31 8
|
30天前
|
Java 应用服务中间件 Nacos
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
51 0
|
30天前
|
监控 数据可视化 安全
一套成熟的Spring Cloud智慧工地平台源码,自主版权,开箱即用
这是一套基于Spring Cloud的智慧工地管理平台源码,具备自主版权,易于使用。平台运用现代技术如物联网、大数据等改进工地管理,服务包括建设各方,提供人员、车辆、视频监控等七大维度的管理。特色在于可视化管理、智能报警、移动办公和分布计算存储。功能涵盖劳务实名制管理、智能考勤、视频监控AI识别、危大工程监控、环境监测、材料管理和进度管理等,实现工地安全、高效的智慧化管理。
|
24天前
|
小程序 JavaScript Java
高校宿舍信息|基于Spring Boot的高校宿舍信息管理系统的设计与实现(源码+数据库+文档)
高校宿舍信息|基于Spring Boot的高校宿舍信息管理系统的设计与实现(源码+数据库+文档)
23 0
|
30天前
|
监控 Java 应用服务中间件
Spring Boot 源码面试知识点
【5月更文挑战第12天】Spring Boot 是一个强大且广泛使用的框架,旨在简化 Spring 应用程序的开发过程。深入了解 Spring Boot 的源码,有助于开发者更好地使用和定制这个框架。以下是一些关键的知识点:
38 6
|
30天前
|
Java 应用服务中间件 测试技术
深入探索Spring Boot Web应用源码及实战应用
【5月更文挑战第11天】本文将详细解析Spring Boot Web应用的源码架构,并通过一个实际案例,展示如何构建一个基于Spring Boot的Web应用。本文旨在帮助读者更好地理解Spring Boot的内部工作机制,以及如何利用这些机制优化自己的Web应用开发。
46 3
|
2天前
|
监控 Java API
【监控】spring actuator源码速读
【监控】spring actuator源码速读
6 1
|
2天前
|
监控 Java 关系型数据库
java版MES系统源码,后端采用 Spring Boot 多模块架构
MES系统采用Vue3的vue-element-plus-admin为后台,Spring Boot多模块架构,支持MySQL、Oracle等数据库,具备SaaS多租户功能。核心功能包括车间计划排程、工艺流程配置、生产质量管理、进度追踪、库存和排班管理等,全面覆盖生产运营关键环节。
java版MES系统源码,后端采用 Spring Boot 多模块架构
|
2天前
|
Java Spring
Spring源码学习——(二)
第二讲——了解BeanFactory的功能
|
3天前
|
Java Spring 容器
Spring源码学习——(一)
第一讲——了解BeanFactory和ApplicationContext