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对象作为参数传入到构造方法中注入进来