Springboot鼓勵零配置的方式,幫你做好大部分重復勞動的事,好到不能再好;具體的Redis安裝方法和Springboot集成Redis方法,可以去搜索相關文章或參考該文章http://www.cnblogs.com/mengmeng89012/p/5519698.html。
當做用戶權限管理時,一般都設置一個session過期時間,以確保用戶長時間不操作時自動退出系統。
Spring seesions的原理可以參考該文章:http://blog.csdn.net/wojiaolinaaa/article/details/62424642
在springboot中設置該值的方法如下:
-
-
-
public class RedisSessionConfig {
-
-
}
即開啟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);
-
}
-