详解SpringBoot中Session超时原理说明
发布时间 - 2026-01-11 03:02:11 点击率:次一:前言:

最近支付后台登录一段时间后如果没有任何操作,总是需要重新登录才可以继续访问页面,出现这个问题的原因就是session超时,debug代码后发现session的超时时间是1800s。也就是说当1800秒内没有任何操作,session就会出现超时现象。那这个超时时间是如何设置的呢?然后该如何重新设置此超时时间呢?系统又如何判断session超时的呢?接下来就一一进行解答。
二:系统session超时时间如何默认的?
说明:获取session超时时间的方法为”request.getSession().getMaxInactiveInterval()",但是tomcat中设置超时时间的参数为“sessionTimeout”,那么他们是怎么联系起来的呢?
第一步:加载sessionTimeout参数。
1、项目运行初始化通过“@ConfigurationProperties”注解加载“org.springframework.boot.autoconfigure.web.ServerProperties”类。
//springBoot中默认的配置文件为"application.yml"或者"application.perties"文件,也就是说server是其中的一个配置参数。
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties
implements EmbeddedServletContainerCustomizer, EnvironmentAware, Ordered {
//代码
}
2、上面类中“ServerProperties”继承自“EmbeddedServletContainerCustomizer”接口。重写customize方法,之后在此方法中“向上推”,即可找到“AbstractConfigurableEmbeddedServletContainer ”类。
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
//多个参数判断,如果在application中没配置的情况下都是null
if (getPort() != null) {
container.setPort(getPort());
}
...//n多个参数判断,
//以下的代码就是重点,因为是tomcat容器,所以以下条件为“真”,经过一系列的查找父类或者实现接口即可找到抽象类“AbstractConfigurableEmbeddedServletContainer”
//public class TomcatEmbeddedServletContainerFactory extends AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware
//public abstract class AbstractEmbeddedServletContainerFactory extends AbstractConfigurableEmbeddedServletContainer implements EmbeddedServletContainerFactory
if (container instanceof TomcatEmbeddedServletContainerFactory) {
getTomcat().customizeTomcat(this,
(TomcatEmbeddedServletContainerFactory) container);
}
//以上代码执行完成之后,实际上已经有对应的session所有的默认参数,之后通过下面方法,将所有参数放入对应的容器中。第3、4步就是设置过程
container.addInitializers(new SessionConfiguringInitializer(this.session));
}
3、在“AbstractConfigurableEmbeddedServletContainer”类中终于可以找到“超时时间”的相关设置
//重要代码
//45行
private static final int DEFAULT_SESSION_TIMEOUT = (int) TimeUnit.MINUTES
.toSeconds(30);
//66行
private int sessionTimeout = DEFAULT_SESSION_TIMEOUT;
@Override
public void setSessionTimeout(int sessionTimeout) {
this.sessionTimeout = sessionTimeout;
}
//171-188行
@Override
public void setSessionTimeout(int sessionTimeout, TimeUnit timeUnit) {
Assert.notNull(timeUnit, "TimeUnit must not be null");
this.sessionTimeout = (int) timeUnit.toSeconds(sessionTimeout);
}
/**
* Return the session timeout in seconds.
* @return the timeout in seconds
*/
public int getSessionTimeout() {
return this.sessionTimeout;
}
4、执行第2步的”Container.addInitializers(new SessionConfiguringInitializer(this.session))“加载所有的配置参数。
public static class Session {
/**
* Session timeout in seconds.
*/
private Integer timeout;
public Integer getTimeout() {
return this.timeout;
}
//将session超时时间设置进来
public void setTimeout(Integer sessionTimeout) {
this.timeout = sessionTimeout;
}
第二步:将上面的超时时间赋值给“MaxInactiveInterval”参数。
说明:既然上面tomcat需要的参数都已经加载完成,那么接下来就会运行tomcat,此处不做细讲,直接进入tomcat启动和加载参数说明。在“TomcatEmbeddedServletContainerFactory”类中的方法调用流程如下:
getEmbeddedServletContainer--》prepareContext--》configureContext--》configureSession--》getSessionTimeoutInMinutes。
1、调用configureSession设置tomcat的Session配置参数。
//以下代码
private void configureSession(Context context) {
long sessionTimeout = getSessionTimeoutInMinutes();
context.setSessionTimeout((int) sessionTimeout);
Manager manager = context.getManager();
if (manager == null) {
manager = new StandardManager();
//此处即为设置相应的参数的位置。之后会调用StandardContext类的setManger(Manager)方法,在setManger中会调用"manager.setContext(this)"
context.setManager(manager);
}
}
//计算超时时间为分钟(注意:此处会将之前的1800秒,转换为30分钟)。可以看出最终的时间结果是个整数的分钟类型,也就是说如果设置的超时时间(单位为秒)不是60的倍数,也会最终转换为60的倍数,并且最小超时时间设置的是60秒。
private long getSessionTimeoutInMinutes() {
long sessionTimeout = getSessionTimeout();
if (sessionTimeout > 0) {
sessionTimeout = Math.max(TimeUnit.SECONDS.toMinutes(sessionTimeout), 1L);
}
return sessionTimeout;
}
2、最终将SessionTimeout赋值给MaxInactiveInterval。终于完成session超时时间设置。
//以下代码
@Override
public void setContext(Context context) {
//省略其余设置代码,直接重新设置Session超时时间,此时又将上面的分钟单位转为秒。此时终于给Sesseion设置了默认超时时间。
if (this.context != null) {
setMaxInactiveInterval(this.context.getSessionTimeout() * 60);
this.context.addPropertyChangeListener(this);
}
}
三:如果自定义超时时间呢?
其实从上面的流程,已经不难看出,只需要在“org.springframework.boot.autoconfigure.web.ServerProperties”类中找到对应的Session参数,初始化让其加载上来即可完成设置。
/**
* Get the session timeout.
* @return the session timeout
* @deprecated since 1.3.0 in favor of {@code session.timeout}.
*/
@Deprecated
@DeprecatedConfigurationProperty(replacement = "server.session.timeout")
public Integer getSessionTimeout() {
return this.session.getTimeout();
}
所以在application中配置“server.session.timeout“即可,参数类型为long类型,单位为”秒“。
四:运行程序是如何判断session超时的?
其实很简单:只需要在每次本次同一个sessionequest请求的时间,和之前的请求时间进行比较,发现两个值的差已经大于MaxInactiveInterval的值即可。
//判断是否超时
@Override
public boolean isValid() {
//省略多个条件判断
if (maxInactiveInterval > 0) {
//判断此session空闲时间是否比maxInactiveInterval大,如果大的情况下,session就超时
int timeIdle = (int) (getIdleTimeInternal() / 1000L);
if (timeIdle >= maxInactiveInterval) {
expire(true);
}
}
return this.isValid;
}
//将上次访问时间和当前时间比较,拿到空闲时间值
@Override
public long getIdleTimeInternal() {
long timeNow = System.currentTimeMillis();
long timeIdle;
if (LAST_ACCESS_AT_START) {
timeIdle = timeNow - lastAccessedTime;
} else {
timeIdle = timeNow - thisAccessedTime;
}
return timeIdle;
}
说明:
所以为了保证session超时时间长点,可以在application配置文件中配置“server.session.timeout”参数即可,参数单位为“秒”,如果参数不是60的整数倍,会转换成60的整数倍(见二:系统如何设置超时时间、步骤二中的“1”中算法)。如不满一分钟,会转换为60秒。
扩展:
实际上也可以直接重写EmbeddedServletContainerCustomizer的customize方法进行赋值。
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer(){
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setSessionTimeout(600);//单位为S
}
};
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# SpringBoot
# Session超时
# session超时原理
# Springboot2 session设置超时时间无效的解决
# 详解springmvc控制登录用户session失效后跳转登录页面
# springboot2中session超时
# 退到登录页面方式
# 加载
# 多个
# 类中
# 转换为
# 就会
# 只需
# 要在
# 也就是说
# 重写
# 配置文件
# 的是
# 都是
# 如何设置
# 情况下
# 是个
# 也会
# 在此
# 整数倍
# 没有任何
# 是怎么
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程
如何在 React 中条件性地遍历数组并渲染元素
原生JS实现图片轮播切换效果
桂林网站制作公司有哪些,桂林马拉松怎么报名?
Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
Laravel如何生成和使用数据填充?(Seeder和Factory示例)
如何在企业微信快速生成手机电脑官网?
如何确认建站备案号应放置的具体位置?
如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】
Mybatis 中的insertOrUpdate操作
PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】
html文件怎么打开证书错误_https协议的html打开提示不安全【指南】
Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案
Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程
高防服务器:AI智能防御DDoS攻击与数据安全保障
Internet Explorer官网直接进入 IE浏览器在线体验版网址
Laravel怎么生成URL_Laravel路由命名与URL生成函数详解
阿里云高弹*务器配置方案|支持分布式架构与多节点部署
如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环
javascript基于原型链的继承及call和apply函数用法分析
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】
Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
实例解析angularjs的filter过滤器
米侠浏览器网页图片不显示怎么办 米侠图片加载修复
再谈Python中的字符串与字符编码(推荐)
Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程
详解Android中Activity的四大启动模式实验简述
ChatGPT常用指令模板大全 新手快速上手的万能Prompt合集
INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】
如何在云主机上快速搭建多站点网站?
如何快速搭建高效简练网站?
Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议
大连网站制作公司哪家好一点,大连买房网站哪个好?
如何获取PHP WAP自助建站系统源码?
无锡营销型网站制作公司,无锡网选车牌流程?
Laravel Octane如何提升性能_使用Laravel Octane加速你的应用
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
详解Oracle修改字段类型方法总结
黑客如何通过漏洞一步步攻陷网站服务器?
Laravel如何实现一对一模型关联?(Eloquent示例)
大学网站设计制作软件有哪些,如何将网站制作成自己app?
高端网站建设与定制开发一站式解决方案 中企动力
如何在建站主机中优化服务器配置?
下一篇:优化Linux系统提升速度
下一篇:优化Linux系统提升速度

