如果要实现集群共享cache,我们就不能用shiro默认的方式处理了。
之前在我的项目当中使用的cacheManager:
<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
<!-- Shiro 配置 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="sessionMode" value="native"></property>
<property name="sessionManager" ref="sessionManager"/>
<property name="cacheManager" ref="cacheManager"/>
<property name="realm" ref="shiroDbRealm" />
</bean>
<bean id="cacheManager" class="com.xinding.travel.security.RedisCacheManager" >
<property name="shiroCacheManager" ref="jedisShiroCacheManager"/>
</bean>
<!-- shiro 缓存实现,对ShiroCacheManager,我是采用redis的实现 -->
<bean id="jedisShiroCacheManager" class="com.xinding.travel.security.JedisShiroCacheManager">
<property name="redisManager" ref="redisManager"/>
</bean>
RedisCacheManager:
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
/**
* Created by Maggie on 2017/7/14.
*/
public class RedisCacheManager implements CacheManager {
private ShiroCacheManager shiroCacheManager;
@Override
public <K, V> Cache<K, V> getCache(String s) throws CacheException {
return getShiroCacheManager().getCache(s);
}
public ShiroCacheManager getShiroCacheManager() {
return shiroCacheManager;
}
public void setShiroCacheManager(ShiroCacheManager shiroCacheManager) {
this.shiroCacheManager = shiroCacheManager;
}
}
JedisShiroCacheManager:
import org.apache.shiro.cache.Cache;
/**
* Created by Maggie on 2017/7/14.
*/
public class JedisShiroCacheManager implements ShiroCacheManager {
public RedisManager getRedisManager() {
return redisManager;
}
public void setRedisManager(RedisManager redisManager) {
this.redisManager = redisManager;
}
private RedisManager redisManager;
@Override
public <K, V> Cache<K, V> getCache(String name) {
return new JedisShiroCache<K, V>(name, getRedisManager());
}
}
JedisShiroCache:
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import java.util.Collection;
import java.util.Set;
/**
* Created by Maggie on 2017/7/14.
*/
public class JedisShiroCache<K, V> implements Cache<K, V> {
/**
* 为了不和其他的缓存混淆,采用追加前缀方式以作区分
*/
private static final String REDIS_SHIRO_CACHE = "shiro_redis_session:";
private RedisManager redisManager;
private String name;
public JedisShiroCache(String name, RedisManager redisManager) {
this.name = name;
this.redisManager = redisManager;
}
@Override
public V get(K k) throws CacheException {
byte[] byteKey = SerializeUtil.serialize(buildCacheKey(k));
byte[] byteValue = new byte[0];
try {
byteValue =redisManager.queryObjectByKey(byteKey);
} catch (Exception e) {
e.printStackTrace();
}
return (V) SerializeUtil.deserialize(byteValue);
}
@Override
public V put(K k, V v) throws CacheException {
V previos = get(k);
try {
redisManager.insertObject(k.toString(),SerializeUtil.serialize(v),0);
} catch (Exception e) {
e.printStackTrace();
}
return previos;
}
@Override
public V remove(K k) throws CacheException {
V previos = get(k);
try {
redisManager.deleteObject(k.toString());
} catch (Exception e) {
e.printStackTrace();
}
return previos;
}
@Override
public void clear() throws CacheException {
}
@Override
public int size() {
return 0;
}
@Override
public Set<K> keys() {
return null;
}
@Override
public Collection<V> values() {
return null;
}
private String buildCacheKey(Object key) {
return REDIS_SHIRO_CACHE + getName() + ":" + key;
}
public String getName() {
if (name == null)
return "";
return name;
}
public void setName(String name) {
this.name = name;
}
}
这样配置之后。我的权限的缓存就会由redis管理。这就满足了shiro集群的要求了。