1. 程式人生 > >Spring 快取註解@Cacheable的用法

Spring 快取註解@Cacheable的用法

        在Spring中通過獲取MemCachedClient來實現與memcached伺服器進行資料讀取的方式。不過,在實際開發中,我們往往是通過Spring的@Cacheable來實現資料的快取的,所以,本文給大家詳細介紹一下@Cacheable的用法。首先,在使用@Cacheable之前,我們要做好準備工作。

第一步:要匯入相應的jar包。
   <classpathentry kind="lib" path="lib/spring-core-4.1.4.RELEASE.jar"/>
    <classpathentry kind="lib" path="lib/spring-cache-1.0.10.jar"/>
    <classpathentry kind="lib" path="lib/spring-context-4.1.4.RELEASE.jar"/>
    <classpathentry kind="lib" path="lib/spring-beans-4.1.4.RELEASE.jar"/>
    <classpathentry kind="lib" path="lib/commons-logging-1.2.jar"/>
    <classpathentry kind="lib" path="lib/log4j-1.2.17.jar"/>
    <classpathentry kind="lib" path="lib/spring-expression-4.1.4.RELEASE.jar"/>
    <classpathentry kind="lib" path="lib/java_memcached-release_2.0.1.jar"/>
    <classpathentry kind="lib" path="lib/spring-aop-4.1.4.RELEASE.jar"/>
    <classpathentry kind="lib" path="lib/spring-aspects-4.1.4.RELEASE.jar"/>
    <classpathentry kind="lib" path="lib/spring-context-support-4.1.4.RELEASE.jar"/>
    <classpathentry kind="lib" path="lib/spring-tx-4.1.4.RELEASE.jar"/>
    <classpathentry kind="lib" path="lib/aopalliance-1.0.jar"/>
    <classpathentry kind="lib" path="lib/ognl-3.0.6.jar"/>
    <classpathentry kind="lib" path="lib/trafficCounter-1.0.2.jar"/>
    <classpathentry kind="lib" path="lib/aspectjweaver-1.8.4.jar"/>
    <classpathentry kind="lib" path="lib/javassist-3.11.0.GA.jar"/>

第二步:xml檔案中增加名稱空間。

<span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans  
	http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	http://www.springframework.org/schema/cache
	http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.1.xsd"></span>
	
之後新增如下宣告:
</pre><pre name="code" class="html"><span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans  
	http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	http://www.springframework.org/schema/cache
	http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.1.xsd">
	
	<!-- 啟用快取註解功能,這個是必須的,否則註解不會生效,另外,該註解一定要宣告在spring主配置檔案中才會生效 --> 
	<cache:annotation-driven cache-manager="cacheManager" />
	
	<!-- cacheManager工廠類,指定ehcache.xml的位置 -->   
	<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">  
		<property name="configLocation"  value="classpath:cache/ehcache.xml"/>  
	</bean>
	
	<!-- 宣告cacheManager -->  
	<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
		<property name="cacheManager" ref="cacheManagerFactory"/>
	</bean>
</beans></span>
第二步: ehcache.xml
<span style="font-size:14px;"><?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" dynamicConfig="false" monitoring="autodetect">  
	<diskStore path="java.io.tmpdir" />
	<!--
		diskStore path:用來配置磁碟快取使用的物理路徑
		name:	快取名稱,cache的唯一標識(ehcache會把這個cache放到HashMap裡)
		eternal="false"   元素是否永恆,如果是就永不過期(必須設定)
		maxElementsOnDisk====磁碟快取中最多可以存放的元素數量,0表示無窮大 
	    maxElementsInMemory="1000" 記憶體快取中最多可以存放的元素數量(必須設定)
	    timeToIdleSeconds="0"   導致元素過期的訪問間隔(秒為單位). 0表示可以永遠空閒,預設為0
	    timeToLiveSeconds="600" 元素在快取裡存在的時間(秒為單位). 0 表示永遠存在不過期
	    overflowToDisk="false"  當快取達到maxElementsInMemory值是,是否允許溢位到磁碟(必須設定)
	    diskPersistent="false"  磁碟快取在VM重新啟動時是否保持(預設為false)
	    diskExpiryThreadIntervalSeconds="100" 磁碟失效執行緒執行時間間隔,預設是120秒
	    memoryStoreEvictionPolicy="LFU" 記憶體儲存與釋放策略.當達到maxElementsInMemory時
	           共有三種策略,分別為LRU(最近最少使用)、LFU(最常用的)、FIFO(先進先出)預設使用"最近使用"策略
	-->
	<defaultCache  
		eternal="false"
		maxElementsInMemory="3000"  
		timeToIdleSeconds="3600"  
		timeToLiveSeconds="0"  
		overflowToDisk="true"  
		diskPersistent="false"  
		diskExpiryThreadIntervalSeconds="100"  
		memoryStoreEvictionPolicy="LRU"/>

	<cache name="propConfigCache"  
		eternal="false"
		maxElementsInMemory="3000"  
		overflowToDisk="true"
		timeToIdleSeconds="0"  
		timeToLiveSeconds="1440" 
		memoryStoreEvictionPolicy="LFU"/>
		
	<cache name="workTimeCache"  
		eternal="false"
		maxElementsInMemory="3000"  
		overflowToDisk="true"
		timeToIdleSeconds="0"  
		timeToLiveSeconds="1440" 
		memoryStoreEvictionPolicy="LFU"/>
	
	<cache name="threeInOneCache"  
		eternal="false"
		maxElementsInMemory="3000"  
		overflowToDisk="true"
		timeToIdleSeconds="0"  
		timeToLiveSeconds="1440" 
		memoryStoreEvictionPolicy="LFU"/>
	
	<cache name="transferCache"  
		eternal="false"
		maxElementsInMemory="1000"  
		overflowToDisk="true"
		timeToIdleSeconds="0"  
		timeToLiveSeconds="1440" 
		memoryStoreEvictionPolicy="LFU"/>
		
	<cache name="threeInOneFavCache"  
		eternal="false"
		maxElementsInMemory="3000"  
		overflowToDisk="true"
		timeToIdleSeconds="0"  
		timeToLiveSeconds="1440" 
		memoryStoreEvictionPolicy="LFU"/>
		
	<cache name="reserveTimeCache"  
		eternal="false"
		maxElementsInMemory="3000"  
		overflowToDisk="true"
		timeToIdleSeconds="0"  
		timeToLiveSeconds="1440" 
		memoryStoreEvictionPolicy="LFU"/>
		
	<cache name="mqServerNameCache"  
		eternal="false"
		maxElementsInMemory="3000"  
		overflowToDisk="true"
		timeToIdleSeconds="0"  
		timeToLiveSeconds="1440" 
		memoryStoreEvictionPolicy="LFU"/>
		
	<cache name="schWorkTimeCache"  
		eternal="false"
		maxElementsInMemory="3000"  
		overflowToDisk="true"
		timeToIdleSeconds="0"  
		timeToLiveSeconds="1440" 
		memoryStoreEvictionPolicy="LFU"/>
		
</ehcache></span>

@Cacheable 支援如下幾個引數:

value:快取位置名稱,不能為空,如果使用EHCache,就是ehcache.xml中宣告的cache的name

key:快取的key,預設為空,既表示使用方法的引數型別及引數值作為key,支援SpEL

condition:觸發條件,只有滿足條件的情況才會加入快取,預設為空,既表示全部都加入快取,支援SpEL

<span style="font-size:14px;">//將快取儲存進andCache,並使用引數中的userId加上一個字串(這裡使用方法名稱)作為快取的key   
@Cacheable(value="andCache",key="#userId + 'findById'")  
public SystemUser findById(String userId) {  
    SystemUser user = (SystemUser) dao.findById(SystemUser.class, userId);        
    return user ;         
}  
//將快取儲存進andCache,並當引數userId的長度小於32時才儲存進快取,預設使用引數值及型別作為快取的key  
@Cacheable(value="andCache",condition="#userId.length < 32")  
public boolean isReserved(String userId) {  
    System.out.println("hello andCache"+userId);  
    return false;  
} </span>

@CacheEvict 支援如下幾個引數:

value:快取位置名稱,不能為空,同上

key:快取的key,預設為空,同上

condition:觸發條件,只有滿足條件的情況才會清除快取,預設為空,支援SpEL

allEntries:true表示清除value中的全部快取,預設為false

 <span style="font-size:14px;">   //清除掉指定key的快取  
    @CacheEvict(value="andCache",key="#user.userId + 'findById'")  
    public void modifyUserRole(SystemUser user) {  
             System.out.println("hello andCache delete"+user.getUserId());  
    }  
      
    //清除掉全部快取  
    @CacheEvict(value="andCache",allEntries=true)  
    public final void setReservedUsers(String[] reservedUsers) {  
        System.out.println("hello andCache deleteall");  
    }</span>  

一般來說,我們的更新操作只需要重新整理快取中某一個值,所以定義快取的key值的方式就很重要,最好是能夠唯一,因為這樣可以準確的清除掉特定的快取,而不會影響到其它快取值 ,

比如我這裡針對使用者的操作,使用(userId+方法名稱)的方式設定key值 ,當然,你也可以找到更適合自己的方式去設定。

EhCache 是一個純Java的程序內快取框架,具有快速、精幹等特點,是Hibernate中預設的CacheProvider。

Ehcache是一種廣泛使用的開源Java分散式快取。主要面向通用快取,Java EE和輕量級容器。它具有記憶體和磁碟儲存,快取載入器,快取擴充套件,快取異常處理程式,一個gzip快取servlet過濾器,支援REST和SOAP api等特點。 Ehcache最初是由Greg Luck於2003年開始開發。2009年,該專案被Terracotta購買。軟體仍然是開源,但一些新的主要功能(例如,快速可重啟性之間的一致性的)只能在商業產品中使用,例如Enterprise EHCache and BigMemory。,維基媒體Foundationannounced目前使用的就是Ehcache技術。
主要的特性有: 1. 快速 2. 簡單 3. 多種快取策略 4. 快取資料有兩級:記憶體和磁碟,因此無需擔心容量問題 5. 快取資料會在虛擬機器重啟的過程中寫入磁碟 6. 可以通過RMI、可插入API等方式進行分散式快取 7. 具有快取和快取管理器的偵聽介面 8. 支援多快取管理器例項,以及一個例項的多個快取區域 9. 提供Hibernate的快取實現