SpringBoot-Shiro中使用缓存(2019.12.15)
在Shiro中加入缓存可以使权限相关操作尽可能快,避免频繁访问数据库获取权限信息,因为对于一个用户来说,其权限在短时间内基本是不会变化的。Shiro提供了Cache的抽象,其并没有直接提供相应的实现,因为这已经超出了一个安全框架的范围。在Shiro中可以集成常用的缓存实现,这里介绍基于Redis
和Ehcache
缓存的实现。
在之前的权限控制中,每调用一次需要权限的Api时候,后台都会去数据库获取用户对应的权限,这对数据库来说是没必要的消耗。接下来使用缓存来解决这个问题。
使用Redis缓存解决
1. (引入依赖)
<!-- shiro-redis -->
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>2.4.2.1-RELEASE</version>
</dependency>
<!-- 对象池,使用redis时必须引入 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
2. 配置Redis在application.yml
配置文件中加入Redis配置
spring:
redis:
host: localhost
port: 6379
timeout: 0ms
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制) 默认 8
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
max-wait: -1ms
# 连接池中的最大空闲连接 默认 8
max-idle: 8
# 连接池中的最小空闲连接 默认 0
min-idle: 0
3. 在ShiroConfig中配置Redis:
public RedisManager redisManager() {
RedisManager redisManager = new RedisManager();
//设置一小时超时 单位是秒
redisManager.setExpire(3600);
return redisManager;
}
/**
* 返回Redis缓存管理器
*
* @return org.crazycake.shiro.RedisCacheManager
* @author: zhihao
* @date: 2019/12/15
*/
public RedisCacheManager cacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager();
redisCacheManager.setRedisManager(redisManager());
return redisCacheManager;
}
//然后添加进web默认安全管理器
@Bean
public DefaultWebSecurityManager securityManager(){
// 配置SecurityManager,并注入shiroRealm
...
//设置管理器记住我
..
//设置缓存管理器
securityManager.setCacheManager(cacheManager());
return securityManager;
}
4. 配置完毕启动项目进行测试
分别访问访问”获取用户信息”、”新增用户”和”删除用户”,可发现后台只打印一次获取权限信息:
启动项目如果出现 :ClassNotFoundException: org.apache.shiro.event.EventBus
异常是因为Maven依赖的jar包中缺少了EventBus这个class文件,原来maven工程中已经依赖了shiro-core1.4.0的版本 ,在shiro-redis依赖中使用了shiro-core-1.2版本,把1.4版本的排除了出去, 而这个类要在1.3版本上才有,所以需要排除1.2版本
<!-- shiro-redis -->
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>2.4.2.1-RELEASE</version>
<exclusions>
<exclusion>
<artifactId>shiro-core</artifactId>
<groupId>org.apache.shiro</groupId>
</exclusion>
</exclusions>
</dependency>
使用Ehcache缓存解决
1.引入依赖
<!-- shiro ehcache -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.3.2</version>
</dependency>
<!-- ehchache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
2.Ehcache配置
在src/main/resource/config
路径下新增一个Ehcache配置——shiro-ehcache.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="java.io.tmpdir/Tmp_EhCache" />
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120" />
<!-- 登录记录缓存锁定1小时 -->
<cache
name="passwordRetryCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true" />
</ehcache>
3.ShiroConfig配置Ehcache
接着在ShiroConfig中注入Ehcache缓存:
@Bean
public EhCacheManager getEhCacheManager() {
EhCacheManager cacheManager = new EhCacheManager();
cacheManager.setCacheManagerConfigFile("classpath:config/shiro-ehcache.xml");
return cacheManager;
}
//将缓存对象注入到SecurityManager中:
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 配置SecurityManager,并注入shiroRealm
...
//设置管理器记住我
..
//设置缓存管理器
securityManager.setCacheManager(getEhCacheManager());
return securityManager;
}
4. 配置完毕启动项目进行测试
分别访问访问”获取用户信息”、”新增用户”和”删除用户”,可发现后台只打印一次获取权限信息: