Springboot2集成Shiro框架(七)使用ehcache緩存

1、pom.xml配置

  • 新增 shiro-ehcache jar
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>cn.junengxiong</groupId>
  <artifactId>springboot-shiro-ehcache</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>springboot-shiro-ehcache Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <!-- Web特性支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!-- shiro ehcache -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-ehcache</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!-- 熱部署模塊 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
            <scope>true</scope>
        </dependency>
    </dependencies>
  <build>
    <finalName>springboot-shiro-ehcache</finalName>
  </build>
</project>

2、在覈心啓動類上新增開啓緩存註解

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@EnableCaching//開啓緩存
@SpringBootApplication
public class SpringBootApp {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootApp.class, args);
    }
}

3、新增ehcache.xml

在resources文件夾下新增ehcache.xml文件,該配置文件來自這裏

<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="ehcache">

    <!--
        緩存對象存放路徑
        java.io.tmpdir:默認的臨時文件存放路徑。
        user.home:用戶的主目錄。
        user.dir:用戶的當前工作目錄,即當前程序所對應的工作路徑。
        其它通過命令行指定的系統屬性,如“java –DdiskStore.path=D:\\abc ……”。
    -->
    <diskStore path="java.io.tmpdir"/>

    <!--

       name:緩存名稱。
       maxElementsOnDisk:硬盤最大緩存個數。0表示不限制
       maxEntriesLocalHeap:指定允許在內存中存放元素的最大數量,0表示不限制。
       maxBytesLocalDisk:指定當前緩存能夠使用的硬盤的最大字節數,其值可以是數字加單位,單位可以是K、M或者G,不區分大小寫,
                          如:30G。當在CacheManager級別指定了該屬性後,Cache級別也可以用百分比來表示,
                          如:60%,表示最多使用CacheManager級別指定硬盤容量的60%。該屬性也可以在運行期指定。當指定了該屬性後會隱式的使當前Cache的overflowToDisk爲true。
       maxEntriesInCache:指定緩存中允許存放元素的最大數量。這個屬性也可以在運行期動態修改。但是這個屬性只對Terracotta分佈式緩存有用。
       maxBytesLocalHeap:指定當前緩存能夠使用的堆內存的最大字節數,其值的設置規則跟maxBytesLocalDisk是一樣的。
       maxBytesLocalOffHeap:指定當前Cache允許使用的非堆內存的最大字節數。當指定了該屬性後,會使當前Cache的overflowToOffHeap的值變爲true,
                             如果我們需要關閉overflowToOffHeap,那麼我們需要顯示的指定overflowToOffHeap的值爲false。
       overflowToDisk:boolean類型,默認爲false。當內存裏面的緩存已經達到預設的上限時是否允許將按驅除策略驅除的元素保存在硬盤上,默認是LRU(最近最少使用)。
                      當指定爲false的時候表示緩存信息不會保存到磁盤上,只會保存在內存中。
                      該屬性現在已經廢棄,推薦使用cache元素的子元素persistence來代替,如:<persistence strategy=”localTempSwap”/>。
       diskSpoolBufferSizeMB:當往磁盤上寫入緩存信息時緩衝區的大小,單位是MB,默認是30。
       overflowToOffHeap:boolean類型,默認爲false。表示是否允許Cache使用非堆內存進行存儲,非堆內存是不受Java GC影響的。該屬性只對企業版Ehcache有用。
       copyOnRead:當指定該屬性爲true時,我們在從Cache中讀數據時取到的是Cache中對應元素的一個copy副本,而不是對應的一個引用。默認爲false。
       copyOnWrite:當指定該屬性爲true時,我們在往Cache中寫入數據時用的是原對象的一個copy副本,而不是對應的一個引用。默認爲false。
       timeToIdleSeconds:單位是秒,表示一個元素所允許閒置的最大時間,也就是說一個元素在不被請求的情況下允許在緩存中待的最大時間。默認是0,表示不限制。
       timeToLiveSeconds:單位是秒,表示無論一個元素閒置與否,其允許在Cache中存在的最大時間。默認是0,表示不限制。
       eternal:boolean類型,表示是否永恆,默認爲false。如果設爲true,將忽略timeToIdleSeconds和timeToLiveSeconds,Cache內的元素永遠都不會過期,也就不會因爲元素的過期而被清除了。
       diskExpiryThreadIntervalSeconds :單位是秒,表示多久檢查元素是否過期的線程多久運行一次,默認是120秒。
       clearOnFlush:boolean類型。表示在調用Cache的flush方法時是否要清空MemoryStore。默認爲true。
       diskPersistent:是否緩存虛擬機重啓期數據 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
       maxElementsInMemory:緩存最大數目
       memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理內存。默認策略是LRU(最近最少使用)。你可以設置爲FIFO(先進先出)或是LFU(較少使用)。
            memoryStoreEvictionPolicy:
               Ehcache的三種清空策略;
               FIFO,first in first out,這個是大家最熟的,先進先出。
               LFU, Less Frequently Used,就是上面例子中使用的策略,直白一點就是講一直以來最少被使用的。如上面所講,緩存的元素有一個hit屬性,hit值最小的將會被清出緩存。
               LRU,Least Recently Used,最近最少使用的,緩存的元素有一個時間戳,當緩存容量滿了,而又需要騰出地方來緩存新的元素的時候,那麼現有緩存元素中時間戳離當前時間最遠的元素將被清出緩存。
    -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="0"
            timeToLiveSeconds="0"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
    />

    <!-- 授權緩存 -->
    <cache name="authorizationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="0"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <!-- 認證緩存 -->
    <cache name="authenticationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="0"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

</ehcache>

4、ShiroConfig配置

  • 新增 myEhCacheManager 方法
  • 修改 myShiroRealm
  • 把 緩存交給管理器 securityManager
/**
	 * 自定義身份認證 realm;
	 * <p>
	 * 必須寫這個類,並加上 @Bean 註解,目的是注入 MyShiroRealm, 否則會影響 MyShiroRealm類 中其他類的依賴注入
	 */
	@Bean
	public MyShiroRealm myShiroRealm() {
		MyShiroRealm myShiroRealm = new MyShiroRealm();
		// 設置密碼比較器
        myShiroRealm.setCredentialsMatcher(CredentialsMatcher());
		// 啓用身份驗證緩存,即緩存AuthenticationInfo信息,默認false
		myShiroRealm.setAuthenticationCachingEnabled(true);
		// 緩存AuthenticationInfo信息的緩存名稱 在ehcache-shiro.xml中有對應緩存的配置
		myShiroRealm.setAuthenticationCacheName("authenticationCache");
		// 啓用授權緩存,即緩存AuthorizationInfo信息,默認false
		myShiroRealm.setAuthorizationCachingEnabled(true);
		// 緩存AuthorizationInfo信息的緩存名稱 在ehcache-shiro.xml中有對應緩存的配置
		myShiroRealm.setAuthorizationCacheName("authorizationCache");
		return myShiroRealm;
	}

@Bean
	public EhCacheManager myEhCacheManager() {
		CacheManager cacheManager = CacheManager.getCacheManager("ehcache");
		EhCacheManager em = new EhCacheManager();
		//因爲配合springboot熱啓動,所以注入bean時加上此判斷,不然會報錯
		if (ObjectUtils.isEmpty(cacheManager)) {
			em.setCacheManagerConfigFile("classpath:ehcache.xml");
		} else {
			em.setCacheManager(cacheManager);
		}
		return em;
	}

/**
	 * 注入 securityManager
	 */
	@Bean
	public SecurityManager securityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(myShiroRealm());
		securityManager.setRememberMeManager(rememberMeManager());
		securityManager.setCacheManager(myEhCacheManager());// 將緩存管理交給ehCache
		return securityManager;
	}


5、手動清除緩存

  1. 在自定義realm中重寫和新增部分方法

    
    /**
     * 重寫方法,清除當前用戶的的 授權緩存
     * @param principals
     */
    public void clearCachedAuthorizationInfo() {
        super.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }

    /**
     * 重寫方法,清除當前用戶的 認證緩存
     * @param principals
     */
    public void clearCachedAuthenticationInfo() {
        super.clearCachedAuthenticationInfo(SecurityUtils.getSubject().getPrincipals());
    }
    /**
     * 清除某個用戶認證和授權緩存
     */
    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    /**
     * 自定義方法:清除所有 授權緩存
     */
    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    /**
     * 自定義方法:清除所有 認證緩存
     */
    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    /**
     * 自定義方法:清除所有的  認證緩存  和 授權緩存
     */
    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }
    
    
  1. 調用清除緩存方法,可以根據需求調用
        RealmSecurityManager rsm = (RealmSecurityManager)SecurityUtils.getSecurityManager();  
        MyShiroRealm realm = (MyShiroRealm)rsm.getRealms().iterator().next(); 
        realm.clearCachedAuthenticationInfo();
        realm.clearCachedAuthorizationInfo();

6、源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章