一、背景描述
1、最近在SpringSession整合Redis的过程中,当session.setAttribute(LOGIN_USER,entity),存入一个实体类对象的时候,这个时候另外一个服务调用request.getSession().getAttribute(key),此时的key和set进去的LOGIN_USERkey不一致。调用的时发现取值的时候报序列化entity这个实体类不存在,当前调用的服务确实没有这个实体类,但是取值的这个key对应的json对象也不是对应这个实体类,这个时候想到是不是sesionn在getAttribute前把所有的值已经取到了。通过查询源码发现
private RedisSession getSession(String id, boolean allowExpired) { Map<Object, Object> entries = getSessionBoundHashOperations(id).entries(); if (entries.isEmpty()) { return null; } MapSession loaded = loadSession(id, entries); if (!allowExpired && loaded.isExpired()) { return null; } RedisSession result = new RedisSession(loaded, false); result.originalLastAccessTime = loaded.getLastAccessedTime(); return result; }
在getsession的时候已经把当前HASH对应键下的所有值取到存在mapsession里面,
查看getAttribute方法
@Override public <T> T getAttribute(String attributeName) { T attributeValue = this.cached.getAttribute(attributeName); if (attributeValue != null && RedisIndexedSessionRepository.this.saveMode.equals(SaveMode.ON_GET_ATTRIBUTE)) { this.delta.put(getSessionAttrNameKey(attributeName), attributeValue); } return attributeValue; }
发现取值是存mapsession取值,这个时候就明白了。先通过redis把对应键下的所有值取到放在map里面,然后取值的时候根据key去匹配。减少对redis的调用