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. 配置完畢啓動項目進行測試
分別訪問訪問”獲取用戶信息”、”新增用戶”和”刪除用戶”,可發現後臺只打印一次獲取權限信息: