美文网首页
使用Spring Session管理会话

使用Spring Session管理会话

作者: 土豆了解一下 | 来源:发表于2018-05-13 13:25 被阅读0次

    Spring Sessio项目提供了一个基于redis的用户会话信息管理。
    Spring Session的快速入门在Spring Boot 中使用Spring Session

    简单的原理分析

    1. 通过@EnableRedisHttpSession注解创建一个名为springSessionRepositoryFilterSessionRepositoryFilter

      @EnableRedisHttpSession源码.png
    2. SessionRepositoryFilter继承了OncePerRequestFilter,而OncePerRequestFilter继承了javax.servlet.FilterOncePerRequestFilter顾名思义,每次请求都会通过该过滤器。查看org.springframework.session.web.http.OncePerRequestFilter#doFilter方法可知,该方法最后会执行org.springframework.session.web.http.OncePerRequestFilter#doFilterInternal抽象方法,而在SessionRepositoryFilter中实现了改抽象方法,代码如下:

    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);
    
        SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(
                request, response, this.servletContext);
        SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(
                wrappedRequest, response);
    
        HttpServletRequest strategyRequest = this.httpSessionStrategy
                .wrapRequest(wrappedRequest, wrappedResponse);
        HttpServletResponse strategyResponse = this.httpSessionStrategy
                .wrapResponse(wrappedRequest, wrappedResponse);
    
        try {
            filterChain.doFilter(strategyRequest, strategyResponse);
        }
        finally {
            wrappedRequest.commitSession();
        }
    }
    
    1. 通过SessionRepositoryFilter过滤器之后,原生的HttpServletRequestHttpServletResponse已经变成了SessionRepositoryRequestWrapperSessionRepositoryResponseWrapperSessionRepositoryRequestWrapper继承了HttpServletRequestWrapperHttpServletRequest的一个包装类,查看该类的getSession方法:
    private S getSession(String sessionId) {
        S session = SessionRepositoryFilter.this.sessionRepository
                .getSession(sessionId);
        if (session == null) {
            return null;
        }
        session.setLastAccessedTime(System.currentTimeMillis());
        return session;
    }   
    

    总结
    通过Filter拦截每一次Http请求,将HttpServletRequest对象做一层包装,业务代码调用getSession方法时,实际上是调用了包装类中的方法SessionRepositoryFilter.this.sessionRepository .getSession(sessionId),而RedisOperationsSessionRepository正是SessionRepository的一个实现类。

    优缺点

    • 会话信息存放在服务端,相对比较安全
    • 用户同时在线量较多时,会占用大量的内存

    相关文章

      网友评论

          本文标题:使用Spring Session管理会话

          本文链接:https://www.haomeiwen.com/subject/tyqldftx.html