Spring全家桶学习之—Spring Session原理及使用

一、Spring Session简介

spring全家桶之一,简单来说就是session + redis的组合,解决了在分布式系统下,不同模块之间session共享的问题。

二、Spring Session 原理

这是我们普通session的实现方案:

在这里插入图片描述

  • 浏览器第一次登录把用户保存在服务器session里面,并且生成一个sessionid返回给浏览器
  • 以后浏览器每一次访问都会带上这个sessionid,后端根据提交的sessionid取出用户信息,校验登录状态。

但是,在分布式系统下不同的服务、又或者相同的服务不同的集群如何共享这个session呢?

解决方法就是这个session,我们可以换一个地方存储,就不能在本地服务了,需要一个公共存放的地方、我们每一个服务都可以轻松访问。

使用DB或者Redis都是一个不错的选择,这个其实就是我们Spring Session实现的原理,如图:

在这里插入图片描述

三、Spring Session整合

1、导入依赖

    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

2、配置redis地址,指定类型为redis

spring:
  redis:
    host: 192.168.56.102
  session:
    store-type: redis

3、启动类上添加注解,全局启用

@EnableRedisHttpSession
public class WebApplication {

4、自定义配置类

@Configuration
public class SessionConfig {

    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
        return new GenericJackson2JsonRedisSerializer();
    }

    @Bean
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer serializer = new DefaultCookieSerializer();
        serializer.setCookieName("HELLOSESSION");
        serializer.setDomainName("hello.com");
        return serializer;
    }
}
  • 由于默认使用jdk进行序列化,通过导入RedisSerializer修改为json序列化
  • 通过修改CookieSerializer扩大session的作用域至**.hello.com

5、SpringSession核心原理 - 装饰者模式

@Override
protected void doFilterInternal(HttpServletRequest request,
                                HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
    request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);

    //对原生的request、response进行包装
    SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(
            request, response, this.servletContext);
    SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(
            wrappedRequest, response);

    try {
        filterChain.doFilter(wrappedRequest, wrappedResponse);
    }
    finally {
        wrappedRequest.commitSession();
    }
}

原生的获取session时是通过HttpServletRequest获取的,这里对request进行包装,并且重写了包装request的getSession()方法。这样我们在项目里面使用spring session就跟使用本地session是一样的。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值