基于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缓存之实战