zoukankan      html  css  js  c++  java
  • spring session源码解析

    模块划分

    core部分代码

    存储实现部分部分:

    jdbc实现

    具体存储的实现类
    例如:org.springframework.session.jdbc.JdbcOperationsSessionRepository

    支持jdbc访问的都可以作为存储介质

    JdbcOperationsSessionRepository通过sql来访问后端存储:

      private static final String CREATE_SESSION_QUERY = "INSERT INTO %TABLE_NAME%(PRIMARY_ID, SESSION_ID, CREATION_TIME, LAST_ACCESS_TIME, MAX_INACTIVE_INTERVAL, EXPIRY_TIME, PRINCIPAL_NAME) VALUES (?, ?, ?, ?, ?, ?, ?)";
      private static final String CREATE_SESSION_ATTRIBUTE_QUERY = "INSERT INTO %TABLE_NAME%_ATTRIBUTES(SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) SELECT PRIMARY_ID, ?, ? FROM %TABLE_NAME% WHERE SESSION_ID = ?";
      private static final String GET_SESSION_QUERY = "SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES FROM %TABLE_NAME% S LEFT OUTER JOIN %TABLE_NAME%_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID WHERE S.SESSION_ID = ?";
      private static final String UPDATE_SESSION_QUERY = "UPDATE %TABLE_NAME% SET SESSION_ID = ?, LAST_ACCESS_TIME = ?, MAX_INACTIVE_INTERVAL = ?, EXPIRY_TIME = ?, PRINCIPAL_NAME = ? WHERE PRIMARY_ID = ?";
      private static final String UPDATE_SESSION_ATTRIBUTE_QUERY = "UPDATE %TABLE_NAME%_ATTRIBUTES SET ATTRIBUTE_BYTES = ? WHERE SESSION_PRIMARY_ID = ? AND ATTRIBUTE_NAME = ?";
      private static final String DELETE_SESSION_ATTRIBUTE_QUERY = "DELETE FROM %TABLE_NAME%_ATTRIBUTES WHERE SESSION_PRIMARY_ID = ? AND ATTRIBUTE_NAME = ?";
      private static final String DELETE_SESSION_QUERY = "DELETE FROM %TABLE_NAME% WHERE SESSION_ID = ?";
      private static final String LIST_SESSIONS_BY_PRINCIPAL_NAME_QUERY = "SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES FROM %TABLE_NAME% S LEFT OUTER JOIN %TABLE_NAME%_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID WHERE S.PRINCIPAL_NAME = ?";
      private static final String DELETE_SESSIONS_BY_EXPIRY_TIME_QUERY = "DELETE FROM %TABLE_NAME% WHERE EXPIRY_TIME < ?";
    

    核心流程


    org.springframework.session.web.http.OncePerRequestFilter包装request和response对象

      protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);
        SessionRepositoryFilter<S>.SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryFilter.SessionRepositoryRequestWrapper(request, response, this.servletContext);
        SessionRepositoryFilter.SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryFilter.SessionRepositoryResponseWrapper(wrappedRequest, response);
    
        try {
          filterChain.doFilter(wrappedRequest, wrappedResponse);
        } finally {
          wrappedRequest.commitSession();
        }
    
      }
    

    org.springframework.session.web.http.SessionRepositoryFilter核心流程:

    • 获取session如果没有判断,是不是因为session无效,无效需要覆盖掉
      -获取session如果有,则如果与当前sessionId不同,则需要回写
      private void commitSession() {
          SessionRepositoryFilter<S>.SessionRepositoryRequestWrapper.HttpSessionWrapper wrappedSession = this.getCurrentSession();
          if (wrappedSession == null) {
            if (this.isInvalidateClientSession()) {
              SessionRepositoryFilter.this.httpSessionIdResolver.expireSession(this, this.response);
            }
          } else {
            S session = wrappedSession.getSession();
            this.clearRequestedSessionCache();
            SessionRepositoryFilter.this.sessionRepository.save(session);
            String sessionId = session.getId();
            if (!this.isRequestedSessionIdValid() || !sessionId.equals(this.getRequestedSessionId())) {
              SessionRepositoryFilter.this.httpSessionIdResolver.setSessionId(this, this.response, sessionId);
            }
          }
    
        }
    

    配置类:org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration

    配置类:org.springframework.session.jdbc.config.annotation.web.http.JdbcHttpSessionConfiguration

    继承SpringHttpSessionConfiguration

    总结:

    通过此次源码阅读,更加理解了接口是面对不同场景或变化时,一种智慧的抽象.

    参考

    https://docs.spring.io/spring-session/docs/current/reference/html5/

  • 相关阅读:
    计算机基础知识
    测试用例设计
    Windows MySql增量备份、完整备份采坑之路
    GOF 的23种JAVA常用设计模式总结 02 UML中的类图与类图之间的关系
    GOF 的23种JAVA常用设计模式总结 01 设计模式的概念分类和功能
    Springboot 整合ApachShiro完成登录验证和权限管理
    玩转Spring全家桶笔记 04 Spring的事务抽象、事务传播特性、编程式事务、申明式事务
    玩转Spring全家桶笔记 03 Spring的JDBC操作以及SQL批处理的实现
    玩转Spring全家桶笔记 02 那些好用的连接池HikariCP
    Springboot token令牌验证解决方案 在SpringBoot实现基于Token的用户身份验证
  • 原文地址:https://www.cnblogs.com/victor2302/p/11831253.html
Copyright © 2011-2022 走看看