SpringBoot-Shiro中使用緩存減輕數據庫壓力( 4 )

SpringBoot-Shiro中使用緩存(2019.12.15)

在Shiro中加入緩存可以使權限相關操作儘可能快,避免頻繁訪問數據庫獲取權限信息,因爲對於一個用戶來說,其權限在短時間內基本是不會變化的。Shiro提供了Cache的抽象,其並沒有直接提供相應的實現,因爲這已經超出了一個安全框架的範圍。在Shiro中可以集成常用的緩存實現,這裏介紹基於RedisEhcache緩存的實現。

在之前的權限控制中,每調用一次需要權限的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. 配置完畢啓動項目進行測試

分別訪問訪問”獲取用戶信息”、”新增用戶”和”刪除用戶”,可發現後臺只打印一次獲取權限信息:

擴展資料:

項目Redis緩存代碼

發佈了29 篇原創文章 · 獲贊 3 · 訪問量 1598
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章