首页 > 数据库 >Spring boot集成Redis实现sessions共享时,sessions过期时间问题分析

Spring boot集成Redis实现sessions共享时,sessions过期时间问题分析

时间:2023-06-15 16:34:31浏览次数:51  
标签:sessionKey sessions Spring boot redis maxInactiveIntervalInSeconds session Strin


Springboot鼓励零配置的方式,帮你做好大部分重复劳动的事,好到不能再好;具体的Redis安装方法和Springboot集成Redis方法,可以去搜索相关文章或参考该文。

 

当做用户权限管理时,一般都设置一个session过期时间,以确保用户长时间不操作时自动退出系统。


在springboot中设置該值的方法如下:

 

1.  
2.  
@EnableRedisHttpSession(maxInactiveIntervalInSeconds= 3600,redisNamespace = "tl")
3.  
public class RedisSessionConfig {
4.   
5.  
}

 

即开启Redis共享sessions的配置类的注解设置maxInactiveIntervalInSeconds的值,单位为秒,默认值为1800秒;问题来了,当设置其为600秒时,在redis的客户端查看sessions的key的过期时间时(redis命令:ttl key,查看其有效时间),发现該值为1100秒;有问题有疑惑找源码,集成redis的代码在spring-sessions包中,找到

org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession注解,该注解的解析类为:
org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration;可以看到
maxInactiveIntervalInSeconds默认值为1800秒,找到setImportMetadata函数:

 
public void setImportMetadata(AnnotationMetadata importMetadata) {
 
 
 
Map<String, Object> enableAttrMap = importMetadata
 
.getAnnotationAttributes(EnableRedisHttpSession.class.getName());
 
AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap);
 
/**
 
*解析注解,获取maxInactiveIntervalInSeconds赋值给配置类的maxInactiveIntervalInSeconds对象
 
*/
 
this.maxInactiveIntervalInSeconds = enableAttrs
 
.getNumber("maxInactiveIntervalInSeconds");
 
String redisNamespaceValue = enableAttrs.getString("redisNamespace");
 
/**
 
*设置命名空间
 
*/
 
if (StringUtils.hasText(redisNamespaceValue)) {
 
this.redisNamespace = this.embeddedValueResolver.resolveStringValue(redisNamespaceValue);
 
}
 
this.redisFlushMode = enableAttrs.getEnum("redisFlushMode");
 
}


	利用Redis作为sessions共享仓实现类为org.springframework.session.data.redis.RedisOperationsSessionRepository
其执行session过期策略的实现类为RedisSessionExpirationPolicy,其过期的具体函数如下:
 
public void onExpirationUpdated(Long originalExpirationTimeInMilli,
 
ExpiringSession session) {
 
String keyToExpire = "expires:" + session.getId();
 
long toExpire = roundUpToNextMinute(expiresInMillis(session));
 
 
 
if (originalExpirationTimeInMilli != null) {
 
long originalRoundedUp = roundUpToNextMinute(originalExpirationTimeInMilli);
 
if (toExpire != originalRoundedUp) {
 
String expireKey = getExpirationKey(originalRoundedUp);
 
this.redis.boundSetOps(expireKey).remove(keyToExpire);
 
}
 
}
 
 
 
long sessionExpireInSeconds = session.getMaxInactiveIntervalInSeconds();
 
String sessionKey = getSessionKey(keyToExpire);
 
 
 
if (sessionExpireInSeconds < 0) {
 
this.redis.boundValueOps(sessionKey).append("");
 
this.redis.boundValueOps(sessionKey).persist();
 
this.redis.boundHashOps(getSessionKey(session.getId())).persist();
 
return;
 
}
 
 
 
String expireKey = getExpirationKey(toExpire);
 
BoundSetOperations<Object, Object> expireOperations = this.redis
 
.boundSetOps(expireKey);
 
expireOperations.add(keyToExpire);
 
/**
 
*关键在此处,在设置的基础上增加了5分钟
 
/
 
long fiveMinutesAfterExpires = sessionExpireInSeconds
 
+ TimeUnit.MINUTES.toSeconds(5);
 
 
 
expireOperations.expire(fiveMinutesAfterExpires, TimeUnit.SECONDS);
 
if (sessionExpireInSeconds == 0) {
 
this.redis.delete(sessionKey);
 
}
 
else {
 
this.redis.boundValueOps(sessionKey).append("");
 
this.redis.boundValueOps(sessionKey).expire(sessionExpireInSeconds,
 
TimeUnit.SECONDS);
 
}
 
this.redis.boundHashOps(getSessionKey(session.getId()))
 
.expire(fiveMinutesAfterExpires, TimeUnit.SECONDS);
 
}
 

标签:sessionKey,sessions,Spring,boot,redis,maxInactiveIntervalInSeconds,session,Strin
From: https://blog.51cto.com/u_4018548/6493207

相关文章

  • springboot文件上传
    前言需要实现文件上传功能需要MultipartResolver接口的实现类的实例,这样才可以实现文件上传而MultipartResolver有两个实现类:StandardServletMultipartResolver:springboot中以自动配置完成,直接使用即可CommonsMultipartResolver:springmvc中使用的是CommonsMultipartReso......
  • Spring之SpEL表达式操作示例解析
    目录1SpEL1.1简介1.2简单示例2深入示例2.1运算2.1.1算术运算2.1.2逻辑运算2.1.3比较运算2.1.4使用字符代替符号2.1.5使用正则表达式2.1.6使用instanceof2.1.7三目运算(if..else..)2.1.8表达式模板TemplateParserContext2.2字符串2.2.1操作2.2.2调用字符串方法2.3使......
  • IDEA Spring Boot Maven 多环境
    源码地址:GiteeGitHub后端https://gitee.com/linjiabin100/pi-admin.githttps://github.com/zengpi/pi-admin.git前端https://gitee.com/linjiabin100/pi-admin-web.githttps://github.com/zengpi/pi-admin-web.git多环境的作用在于允许在不同的运行环境中......
  • 15 Spring核心注释示例
    我们经常将这些称为“Spring核心注释”,我们将在本文中对它们进行审核。这是所有已知的Spring核心注释的列表。@Autowired我们可以使用  @Autowired 注释  来标记Spring将要解析和注入的依赖关系。我们可以将这个注释与构造函数,setter或字段注入一起使用。构造函数注入:@RestCon......
  • springboot 自定义listener 添加环境变量。 抄的springboot项目去掉了一些不用的ja
    1.自定义listener实现 ApplicationListener<ApplicationEnvironmentPreparedEvent>,Ordered(如果要设置优先级可以实现Ordered接口,注意order值越小优先级越高)publicclassMyListenerimplementsApplicationListener<ApplicationEnvironmentPreparedEvent>,Ordered{......
  • ajax请求springboot
    老是忘记ajax请求格式,记录一下吧后面看自己的functionsave(){varURL="/reconciliation/wzglWzMaterilApplicationDetail/saveSupplier";varcc=JSON.stringify({data:"world",p:{pag:0,pageS......
  • springboot项目启动失败之 org.springframework.boot.env.OriginTrackedYamlLoader.cr
    1、检查一下父项目的module的依赖是否,以及版本是否一致。例如<dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.30</version></dependency>2、如何知道自己的org.yaml的版本,可以双击Shift键,输入如图所示,注意划红线的地方就是......
  • springboot优点
    传统的Spring应用部署时,通常会将应用打成WAR包形式并部署到Tomcat、Jetty或Undertow服务器中。 SpringBoot框架内嵌了Tomcat、Jetty和Undertow服务器,于是可以将应用打包成jar,直接运行一个jar包就能启动一个web服务 是怎么内嵌的tomcat 这个依赖是SpringBootStar......
  • spring boot请求接口地址报404的几种情况
     1接口地址错误,这个不用解释了吧,就是地址搞错了2请求方法错误,如:get,你用了post3使用了springsecurity,没有开放这个接口,导致请求不到4在application.yml的配置文件里为servlet添加了context-path配置,如:server:port:8129servlet:context-path:/share这个......
  • 如何在Spring Boot中使用Hibernate Natural ID
    首先,让我们关注所需类的实现。完成所有这些后,我们将能够为具有自然ID的实体提供存储库。用自然ID编写实体让我们考虑以下具有自动生成ID和自然ID(code列)的实体。这只是一个使用一个自然ID的典型实体@NaturalId:@实体publicclassProductimplementsSerializable{priva......