在集成shiro框架之后,每次在访问设置了权限的页面时,都会去执行doGetAuthorizationInfo方法来判断当前用户是否具备访问权限,由于在实际情况中,权限是不会经常改变的,所以进行缓存。
一、shiro缓存实现原理。
Shiro 提供了一系列让我们自己实现的接口,包括org.apache.shiro.cache.CacheManager 、org.apache.shiro.cache.Cache 等接口。那么我们要对这些做实现,就实现了 Shiro 对 Session 和用户认证信息、用户缓存信息等的缓存,存储。我们可以用缓存,如 Redis 、 memcache 、 EHCache 等,甚至我们可以用数据库,如 Oracle 、 Mysql 等,都可以,只有效率的快慢问题,功能都可以达到。
二、添加缓存
1、Ehcache缓存
由于shiro默认集成了Ehcache缓存,所以这部分的配置比较简单。
(1)生成EhCacheManager(org.apache.shiro.cache.ehcache.EhCacheManager)bean。
/*EhcacheManager */public EhCacheManager ehCacheManager(){ EhCacheManager ehCacheManager = new EhCacheManager(); //配置Ehcache缓存配置文件,该缓存配置文件默认位置为“classpath:org/apache/shiro/cache/ehcache/ehcache.xml” //ehCacheManager.setCacheManagerConfigFile(FileLocation) return ehCacheManager;}
(2)将其注入SecurityManager中,此时即已经集成Ehcache缓存。
@Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //设置realm securityManager.setRealm(myShiroRealm()); //注入缓存管理器 securityManager.setCacheManager(ehCacheManager());// //注入sessionDao// securityManager.setSessionManager(SessionManager()); return securityManager; }
tip:在配置Ehcache缓存的时候碰到一个问题,配置的缓存不生效,且登录之后一旦访问访问需要权限的目录就回跳转至登录页面。
在调试排查之后发现,是由于我之前配置了
此依赖的作用为redis的session存储,之前的问题是由于此依赖的影响。移除此依赖后,缓存生效。
2、Redis缓存
这里我们就需要自定义实现SessionDao,Cache,CacheManager接口,这一部分其他人早已经做过,我们可以直接拿过来用。
(1)配置依赖
org.crazycake shiro-redis 2.4.2.1-RELEASE
(2)配置config类
//redisManager,包含一个jedisPool,提供jedisClient用来连接redispublic RedisManager redisManager(){ RedisManager redisManager = new RedisManager(); redisManager.setHost("127.0.0.1"); redisManager.setPort(6379); redisManager.setExpire(1800);// 配置过期时间 // redisManager.setTimeout(timeout); // redisManager.setPassword(password); return redisManager;}/** * cacheManager 缓存 redis实现 * * @return */public RedisCacheManager cacheManager() { RedisCacheManager redisCacheManager = new RedisCacheManager(); redisCacheManager.setRedisManager(redisManager()); return redisCacheManager;}/** * RedisSessionDAO shiro sessionDao层的实现 通过redis */public RedisSessionDAO redisSessionDAO() { RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); redisSessionDAO.setRedisManager(redisManager()); return redisSessionDAO;}/** * shiro session的管理 */public DefaultWebSessionManager SessionManager() { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setSessionDAO(redisSessionDAO()); return sessionManager;}
(3)将RedisCacheManager和DefaultWebSessionManager注入SecurityManager
@Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //设置realm securityManager.setRealm(myShiroRealm()); //注入缓存管理器 securityManager.setCacheManager(cacheManager()); //注入sessionDao securityManager.setSessionManager(SessionManager()); return securityManager; }
此时,redis缓存已经集成完毕。
三、测试缓存是否配置成功
访问权限资源,当连续访问多次,doGetAuthorizationInfo只执行一次时,缓存配置成功。
以上只是最简单的缓存配置,后续计划实现session通过redis集群共享,Ehcache+redis二级缓存实现。