shiro 集成spring 使用 redis作为缓存 学习记录(六)
1、在applicationContext-redis.xml配置文件中增加如下: 申明一个cacheManager对象 用来注入到 shiro的 securityManager 属性 cacheManager 中
1 <!--spring rediscache--> 2 <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager" 3 c:redisOperations-ref="redisTemplate"> 4 <!-- 默认缓存10分钟 --> 5 <property name="defaultExpiration" value="10"/> 6 <!-- key:prefix --> 7 <property name="usePrefix" value="true"/> 8 <!-- cacheName 缓存超时配置,半小时,一小时,一天 --> 9 <property name="expires"> 10 <map key-type="java.lang.String" value-type="java.lang.Long"> 11 <entry key="halfHour" value="1800"/> 12 <entry key="hour" value="3600"/> 13 <entry key="oneDay" value="86400"/> 14 <entry key="itzixiCaptcha" value="500"/> 15 <!-- shiro cache keys --> 16 <entry key="authenticationCache" value="1800"/><!-- 用户每次操作后会要等缓存过期后会重新再取 --> 17 <entry key="authorizationCache" value="1800"/><!-- 用户每次操作后会要等缓存过期后会重新再取 --> 18 <entry key="activeSessionCache" value="1800"/><!-- 用户session每次操作后会重置时间 --> 19 </map> 20 </property> 21 </bean> 22 23 <!-- cache注解,项目中如果还存在shiro的ehcache的话,那么本文件和spring-ehcache.xml中的只能使用一个 --> 24 <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
2、编写这两个 ShiroSpringCache.java
1 import java.util.Collection; 2 import java.util.Collections; 3 import java.util.Set; 4 5 import org.apache.shiro.cache.CacheException; 6 import org.slf4j.Logger; 7 import org.slf4j.LoggerFactory; 8 import org.springframework.cache.Cache; 9 import org.springframework.cache.Cache.ValueWrapper; 10 11 /** 12 * 13 * @Title: ShiroSpringCache.java 14 * @Description: 实现spring cache作为shiro的缓存 15 * @date 2017年10月14日 下午12:08:56 16 * @version V1.0 17 */ 18 @SuppressWarnings("unchecked") 19 public class ShiroSpringCache<K, V> implements org.apache.shiro.cache.Cache<K, V> { 20 final static Logger logger = LoggerFactory.getLogger(ShiroSpringCache.class); 21 22 private final org.springframework.cache.Cache cache; 23 24 public ShiroSpringCache(Cache cache) { 25 if (cache == null) { 26 throw new IllegalArgumentException("Cache argument cannot be null."); 27 } 28 this.cache = cache; 29 } 30 31 @Override 32 public V get(K key) throws CacheException { 33 if (logger.isTraceEnabled()) { 34 logger.trace("Getting object from cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass()); 35 } 36 ValueWrapper valueWrapper = cache.get(key); 37 if (valueWrapper == null) { 38 if (logger.isTraceEnabled()) { 39 logger.trace("Element for [" + key + "] is null."); 40 } 41 return null; 42 } 43 return (V) valueWrapper.get(); 44 } 45 46 @Override 47 public V put(K key, V value) throws CacheException { 48 if (logger.isTraceEnabled()) { 49 logger.trace("Putting object in cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass()); 50 } 51 V previous = get(key); 52 cache.put(key, value); 53 return previous; 54 } 55 56 @Override 57 public V remove(K key) throws CacheException { 58 if (logger.isTraceEnabled()) { 59 logger.trace("Removing object from cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass()); 60 } 61 V previous = get(key); 62 cache.evict(key); 63 return previous; 64 } 65 66 @Override 67 public void clear() throws CacheException { 68 if (logger.isTraceEnabled()) { 69 logger.trace("Clearing all objects from cache [" + this.cache.getName() + "]"); 70 } 71 cache.clear(); 72 } 73 74 @Override 75 public int size() { 76 return 0; 77 } 78 79 @Override 80 public Set<K> keys() { 81 return Collections.emptySet(); 82 } 83 84 @Override 85 public Collection<V> values() { 86 return Collections.emptySet(); 87 } 88 89 @Override 90 public String toString() { 91 return "ShiroSpringCache [" + this.cache.getName() + "]"; 92 } 93 }
ShiroSpringCacheManager.java
1 import org.apache.shiro.cache.Cache; 2 import org.apache.shiro.cache.CacheException; 3 import org.apache.shiro.cache.CacheManager; 4 import org.apache.shiro.util.Destroyable; 5 import org.slf4j.Logger; 6 import org.slf4j.LoggerFactory; 7 8 /** 9 * 10 * @Title: ShiroSpringCacheManager.java 11 * @Description: 实现shiro的cacheManager 12 * @date 2017年10月14日 下午12:09:49 13 * @version V1.0 14 */ 15 public class ShiroSpringCacheManager implements CacheManager, Destroyable { 16 17 final static Logger logger = LoggerFactory.getLogger(ShiroSpringCacheManager.class); 18 19 private org.springframework.cache.CacheManager cacheManager; 20 21 public org.springframework.cache.CacheManager getCacheManager() { 22 return cacheManager; 23 } 24 25 public void setCacheManager(org.springframework.cache.CacheManager cacheManager) { 26 this.cacheManager = cacheManager; 27 } 28 29 @Override 30 public <K, V> Cache<K, V> getCache(String name) throws CacheException { 31 if (logger.isTraceEnabled()) { 32 logger.trace("Acquiring ShiroSpringCache instance named [" + name + "]"); 33 } 34 org.springframework.cache.Cache cache = cacheManager.getCache(name); 35 return new ShiroSpringCache<K, V>(cache); 36 } 37 38 @Override 39 public void destroy() throws Exception { 40 cacheManager = null; 41 } 42 43 }
3、在applicationContext-shiro.xml配置文件中增加:
1 <!-- 用户授权信息Cache, 采用spring-cache, --> 2 <bean id="shiroRedisCacheManager" class="com.itzixi.web.shiro.ShiroSpringCacheManager"> 3 <property name="cacheManager" ref="cacheManager"/> 4 </bean>
4、修改shiro安全管理器的使用对象如:
5、使用redis作为shiro的缓存注意,因为shiro的缓存是一个实体的对象,所有在序列化的时候必须使用jdk序列化
6、同时需要配置自定义Realm中开启缓存的配置,认证缓存、权限缓存、seesion缓存
7、在自定义Realm中 将配置的shiroReadisCacheManager对象作为参数传入到构造方法中注入进来