接管shiro的缓存只需要重写SessionDAO
实现。
spring-shrio.xml相关配置
<!--session操作-->
<bean id="shiroRedisSessionDAO" class="com.sdhs.mob.common.shiro.ShiroRedisSessionDAO">
<constructor-arg ref="redisTemplate"/>
<property name="sessionIdGenerator">
<bean class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
</property>
</bean>
<!--session管理器-->
<bean id="shiroRedisSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionDAO" ref="shiroRedisSessionDAO"/>
<!--超时 ms-->
<property name="globalSessionTimeout" value="1800000"/>
<!-- 相隔多久检查一次session的有效性 -->
<property name="sessionValidationInterval" value="900000"/>
<!-- 删除失效session -->
<property name="deleteInvalidSessions" value="true"/>
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--单个realm使用realm,如果有多个realm,使用realms属性代替 -->
<property name="realm" ref="shiroRealm"/>
<!-- 使用session管理器 -->
<property name="sessionManager" ref="shiroRedisSessionManager"/>
</bean>
这里的sessionManager使用的默认的 DefaultWebSessionManager
,只重写了sessionDAO实现
ShiroRedisSessionDAO
ShiroRedisSessionDAO.java
package com.sdhs.mob.common.shiro;
import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* shiro redis session
*
* @author seer
* @date 2018/3/25 10:38
*/
public class ShiroRedisSessionDAO extends AbstractSessionDAO {
private static Logger LOGGER = LogManager.getLogger(ShiroRedisSessionDAO.class);
/**
* key前缀
*/
private static final String SHIRO_REDIS_SESSION_KEY_PREFIX = "shiro.redis.session_";
private RedisTemplate redisTemplate;
private ValueOperations valueOperations;
public ShiroRedisSessionDAO(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
this.valueOperations = redisTemplate.opsForValue();
}
@Override
protected Serializable doCreate(Session session) {
Serializable sessionId = this.generateSessionId(session);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("shiro redis session create. sessionId={}", sessionId);
}
this.assignSessionId(session, sessionId);
valueOperations.set(generateKey(sessionId), session, session.getTimeout(), TimeUnit.MILLISECONDS);
return sessionId;
}
@Override
protected Session doReadSession(Serializable sessionId) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("shiro redis session read. sessionId={}", sessionId);
}
return (Session) valueOperations.get(generateKey(sessionId));
}
@Override
public void update(Session session) throws UnknownSessionException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("shiro redis session update. sessionId={}", session.getId());
}
valueOperations.set(generateKey(session.getId()), session, session.getTimeout(), TimeUnit.MILLISECONDS);
}
@Override
public void delete(Session session) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("shiro redis session delete. sessionId={}", session.getId());
}
redisTemplate.delete(generateKey(session.getId()));
}
@Override
public Collection<Session> getActiveSessions() {
Set<Object> keySet = redisTemplate.keys(generateKey("*"));
Set<Session> sessionSet = new HashSet<>();
if (CollectionUtils.isEmpty(keySet)) {
return Collections.emptySet();
}
for (Object key : keySet) {
sessionSet.add((Session) valueOperations.get(key));
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("shiro redis session all. size={}", sessionSet.size());
}
return sessionSet;
}
/**
* 重组key
* 区别其他使用环境的key
*
* @param key
* @return
*/
private String generateKey(Object key) {
return SHIRO_REDIS_SESSION_KEY_PREFIX + this.getClass().getName() +"_"+ key;
}
}
这里使用的redisTemplate
操作redis,直接使用redisConnection
操作redis可以参考:Spring中使用Redis做为Mybatis二级缓存
直接实现CachingSessionDAO
可以最快的实现redis管理session
ShiroRedisCacheSessionDAO.java
package com.sdhs.mob.common.shiro;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
import java.io.Serializable;
/**
* ShiroRedisCacheSessionDAO
*
* @author seer
* @date 2018/3/25 16:03
*/
public class ShiroRedisCacheSessionDAO extends CachingSessionDAO {
@Override
protected void doUpdate(Session session) {
this.getCacheManager().getCache(this.getClass().getName()).put(session.getId(), session);
}
@Override
protected void doDelete(Session session) {
this.getCacheManager().getCache(this.getClass().getName()).remove(session.getId());
}
@Override
protected Serializable doCreate(Session session) {
Serializable sessionId = this.generateSessionId(session);
this.assignSessionId(session, sessionId);
this.getCacheManager().getCache(this.getClass().getName()).put(session.getId(), session);
return sessionId;
}
@Override
protected Session doReadSession(Serializable sessionId) {
return (Session) this.getCacheManager().getCache(this.getClass().getName()).get(sessionId);
}
}
需要配置好cacheManager,参考文档:Spring集成shiro使用redis做缓存
网友评论