91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

詳解SpringBoot中Session超時原理說明

發布時間:2020-08-31 11:23:03 來源:腳本之家 閱讀:344 作者:james__Gao 欄目:編程語言

一:前言:

最近支付后臺登錄一段時間后如果沒有任何操作,總是需要重新登錄才可以繼續訪問頁面,出現這個問題的原因就是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
   }
  };
 }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武鸣县| 东方市| 康平县| 繁昌县| 梓潼县| 澜沧| 临江市| 壤塘县| 光泽县| 虞城县| 勃利县| 磴口县| 滨州市| 清水河县| 敖汉旗| 得荣县| 牡丹江市| 永德县| 涞源县| 桐城市| 临清市| 盐津县| 平利县| 岳池县| 额敏县| 图片| 阜平县| 乐安县| 宜阳县| 宽甸| 绥阳县| 商河县| 嘉兴市| 康马县| 谷城县| 双鸭山市| 乌拉特后旗| 三原县| 长沙县| 正镶白旗| 和平县|