SpringBoot-SpringSession源码分析

spring-session是用于分布式系统共享HttpSession的,可以与spring-boot结合使用,默认使用Redis作为介质。

1. EnableRedisHttpSession启用SpringSession

@Import(RedisHttpSessionConfiguration.class)
public @interface EnableRedisHttpSession {}

2. RedisHttpSessionConfiguration创建Filter

@Bean
public ... springSessionRepositoryFilter(SessionRepository sessionRepository, ...) {
    SessionRepositoryFilter sessionRepositoryFilter = new SessionRepositoryFilter(sessionRepository);
    sessionRepositoryFilter.setServletContext(servletContext);
    if(httpSessionStrategy != null) {
        sessionRepositoryFilter.setHttpSessionStrategy(httpSessionStrategy);
    }
    return sessionRepositoryFilter;
}
  • SessionRepository接口,把HttpSession数据持久化。提供了两个实现类MapSessionRepository, RedisOperationsSessionRepository。默认使用后者,把数据保存到Redis
  • HttpSessionStrategy接口,获取sessionId的策略。提供了两个实现类HeaderHttpSessionStrategyCookieHttpSessionStrategy。默认使用后者,从Cookie中获取

3. SessionRepositoryFilter拦截所有请求

@Order(SessionRepositoryFilter.DEFAULT_ORDER)
public class SessionRepositoryFilter<...> extends OncePerRequestFilter {
    public static final int DEFAULT_ORDER = Integer.MIN_VALUE + 50;
}
  • 设定SessionRepositoryFilter的优先级,先运行
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) ... {
    ...

    SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(request, response, servletContext);
    SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(wrappedRequest,response);

    HttpServletRequest strategyRequest = httpSessionStrategy.wrapRequest(wrappedRequest, wrappedResponse);
    HttpServletResponse strategyResponse = httpSessionStrategy.wrapResponse(wrappedRequest, wrappedResponse);

    try {
        filterChain.doFilter(strategyRequest, strategyResponse);
    } finally {
        wrappedRequest.commitSession();
    }
}
  • SessionRepositoryRequestWrapperHttpServletRequest的子类,接管原来的request,重写了与session相关的方法
  • SessionRepositoryResponseWrapperHttpServletResponse的子类,接管原来的response

你可能感兴趣的:(SpringBoot-SpringSession源码分析)