shiro缓存管理
shiro缓存现象
shiro缓存主要就是换成用户的授权信息,就是将我们的自定义realm的doGetAuthorizationInfo方法就是给用户授权的方法进行缓存.
如果不使用缓存,那么每次进行用户权限判断的时候就会调用一下授权方法:
我请求一下isPermitted就会调用一下授权方法,
如果我设置了缓存:
这时候不过请求多少次都只会调用一次授权,如果退出就会删除缓存
缓存源码分析
首先看shiro架构图(这个图重要的要人命,建议作为屏保壁纸):
CacheManager就是在SecurityManager内部,所以,SecurityManager肯定有个setCacheManager方法,前面在讲SecurityManager的时候,不知道你们还记不记得,当时将DefaultSecurityManager的uml图的时候,是不是有个
Realm里面也有个缓存Cachingrealm,别搞混了.毫无疑问,方法肯定在CachingSecurityManager里面了,直接通过defaultWebSecurityManager.setCacheManager里面点进去就到CachingSecurityManager里面了,传入的是个CacheManager,注意,CachingSecurityManager实现的是CacheManagerAware,而这个CacheManagerAware就像spring中的Aware接口,为了能让类能够感知到自身的一些属性.
shiro提供的基于内存的CacheManager
使用缓存如上面,直接加在 defaultWebSecurityManager.setCacheManager()即可.
直接看CacheManager的实现:MemoryConstrainedCacheManager
这个类是Shiro提供的一个简单的缓存处理器,就是返回一个简单的Cache的实现基于Map的:
就不细说了,比较简单.
基于Ehcache的缓存
引入对应的pom,注意如果shiro你直接引入的shiro-all的话,应该就不用引入shiro-ehcache包了.
<!-- ehcache-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-ehcache -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.2</version>
</dependency>
然后直接 webSecurityManager.setCacheManager(new EhCacheManager());
测试结果也是一样的,我这里没有使用自定义ehcache的配置文件,因为提供了一个默认的配置文件,小伙伴可以自定义配置文件,直接通过EhCacheManagerFactoryBean来创建ehcacheManager就可以了,然后注入到EhCacheManager:
基于Redis的缓存
我们可以直接实现,但是感觉有点麻烦,又要自己实现RedisCacheManager又要重写sessionDao实现自定义session管理,所以,简单点,使用开源的shiro-redis包即可,使用跟ehcache一样,也会很简单,直接将cachemanager缓存redisCachemanager即可:
前面使用的user是map对象,然后整合会报错,说没有getId方法,然后我就创了一个user对象,然后就可以了,大概是因为,存入redis的时候需要set,get方法吧:
首先引入shiro-redis包,引入了jedis就可以不用引入了,
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>3.2.3</version>
<exclusions>
<exclusion>
<artifactId>shiro-core</artifactId>
<groupId>org.apache.shiro</groupId>
</exclusion>
</exclusions>
</dependency>
然后配置redisCacheManager类:
@Bean
public RedisCacheManager redisCacheManager() {
RedisManager redisManager = new RedisManager();
redisManager.setHost("localhost:6379");
redisManager.setDatabase(1);
redisManager.setTimeout(5000);
// redisManager.setPassword();
RedisCacheManager redisCacheManager = new RedisCacheManager();
redisCacheManager.setRedisManager(redisManager);
return redisCacheManager;
}
然后还是直接射进去就好了:
这是存入redis里面的数据:
然后,redis的配置我直接写在代码里面了,具体使用应该写到配置文件里面.
ok,使用就完成了…