基于SpringSession结合redis做session共享与监听

Posted itLaity

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于SpringSession结合redis做session共享与监听相关的知识,希望对你有一定的参考价值。

生命无罪,健康万岁,我是laity。

我曾七次鄙视自己的灵魂:

第一次,当它本可进取时,却故作谦卑;

第二次,当它在空虚时,用爱欲来填充;

第三次,在困难和容易之间,它选择了容易;

第四次,它犯了错,却借由别人也会犯错来宽慰自己;

第五次,它自由软弱,却把它认为是生命的坚韧;

第六次,当它鄙夷一张丑恶的嘴脸时,却不知那正是自己面具中的一副;

第七次,它侧身于生活的污泥中,虽不甘心,却又畏首畏尾。

SpringSession

用于解决分布式下Session不共享,不同步问题

核心原理


核心代码分析

结论:包装模式(装饰者模式)

/**
 * SpringSession核心原理
 *  1、@EnableRedisHttpSession 导入了 @Import(RedisHttpSessionConfiguration.class)
 *    1)、给容器中添加了一个组件
 *      RedisIndexedSessionRepository:redis操作session,session的增删改查的封装类
 *    2)、SessionRepositoryFilter:session存储过滤器  ==> Filter:每个请求都经过过滤器
 *      创建的时候,就自动从容器中获取到了SessionRepository;
 *      原始的request、response都被包装
 *      从原始的 request.getSession() => wrappedRequest.getSession(); => private final SessionRepository<S> sessionRepository; 中获取
 *      private final SessionRepository<S> sessionRepository;  | redis、jdbc、mangodb
 *      所以只是用了包装模式(装饰者模式)
 *      并且 springSession会自动延期session时间,浏览器一关就删除session
 */

SpringBoot整合SpringSession

  • 导入依赖
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
            <version>2.3.0.RELEASE</version>  <!--这个版本是我Springboot版本-->
        </dependency>
  • application.yml
server:
  servlet:
    session:
      timeout: 30m  # session的过期时间
spring:
  redis:   # Redis配置
    port: 你本人Redis端口
    host: 你本人Redis服务地址
    password: 你本人Redis服务密码(有则写)
  session: # 指定session处理的store-type(就是存储位置)
    store-type: redis
  • 开启SpringSession

@EnableRedisHttpSession

@EnableRedisHttpSession  // SpringSession解决session共享问题:整合redis做为我们session的存储
@EnableDiscoveryClient
@EnableAsync
@ServletComponentScan
@EnableFeignClients(basePackages = "com.laity.auth.feign")
@SpringBootApplication
public class GulimallAuthServerApplication 

    public static void main(String[] args) 
        SpringApplication.run(GulimallAuthServerApplication.class, args);
    
    

  • 业务代码

session共享应用于 登录接口:账号密码登录和社交登录(qq、微信等)

    @GetMapping(value = "/gitee/success", "/github/success")
    @ApiOperation(value = "获取gitee授权码", notes = "access_token获取用户信息")
    public String git(@RequestParam("code") String code, HttpSession session) throws Exception 
    		// ......此处省略与案例不相关代码
            session.setAttribute("你的key", "你的数据");
            // 这里如果要往Redis中存入内存对象,那么一定不要忘记将你要存入的对象进行序列化操作
            // ......此处省略与案例不相关代码
    
  • Session共享

分布式下 Session令牌Cookie只能分配到当前域名下,而其他域名无法共享该Session,所以要扩大Session令牌的作用域,解决Session子域共享问题

@Configuration
public class MySessionConfig 

    /*默认发的令牌。当前域(解决子域session共享问题)*/
    @Bean
    public CookieSerializer cookieSerializer() 
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        //放大作用域
        cookieSerializer.setDomainName(".laity.com");  // 我这里直接domain的作用域扩大到主域名下
        cookieSerializer.setCookieName("SESSION"); // 自定义令牌名
        return cookieSerializer;
    

    /*使用JSON的序列化方式来序列化对象到Redis中 - 序列化机制*/
    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() 
        return new GenericJackson2JsonRedisSerializer();
    
    

遇到的问题

错误1 并解决

setting spring.main.allow-bean-definition-overriding=true

这个配置一般会写在springboot的application.properties下面

这个配置主要是声明spring框架是否允许定义重名的bean对象覆盖原有的bean (spring boot默认是false)

spring.main.allow-bean-definition-overriding = true 就是允许定义相同的bean对象 去覆盖原有的
spring.main.allow-bean-definition-overriding = false 就行不允许定义同名的bean对象

这里只是强调下 setting spring.main.allow-bean-definition-overriding=true 的作用
我报这个错误的原因是因为我将@EnableRedisHttpSession写错了

错误2 并解决

Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException:

将内存对象存入redis中 - 所以要先将对象序列化为流或者二进制数据,对应的类需要实现Serializable接口
implements Serializable

@Data
public class UserResponseBO implements Serializable 
	private String name;
	private Integer gender;

真正的精通需要自己去不断摸索,谢谢观看~

以上是关于基于SpringSession结合redis做session共享与监听的主要内容,如果未能解决你的问题,请参考以下文章

SpringSpringBoot + SpringSession + Redis 实现Session共享

springboot集成springsession利用redis来实现session共享

SpringBoot SpringSession redis 共享 SESSION

spring boot 学习(十四)SpringBoot+Redis+SpringSession缓存之实战

使用idea,springboot,springsession,redis实现分布式微服务的session 共享

spring session是怎么把session存入redis的