• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

详解SpringBoot中Session超时原理说明

springboot 搞代码 4年前 (2022-01-05) 39次浏览 已收录 0个评论

本篇文章主要介绍了详解SpringBoot中Session超时原理说明,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

一:前言:

最近支付后台登录一段时间后如果没有任何操作,总是需要重新登录才可以继续访问页面,出现这个问题的原因就是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.sessionTi<strong style="color:transparent">来源gaodai#ma#com搞@代~码网</strong>meout = (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 } }; } 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持gaodaima搞代码网

以上就是详解SpringBoot中Session超时原理说明的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:详解SpringBoot中Session超时原理说明

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址