Echache整合Spring緩存實例講解
林炳文Evankaka原創作品。轉載請注明出處http://blog.csdn.net/evankaka
摘要:本文主要介紹了EhCache,并通過整合Spring給出了一個使用實例。
一、EhCache 介紹
EhCache 是一個純Java的進程內緩存框架,具有快速、精干等特點,是Hibernate中默認的CacheProvider。Ehcache是一種廣泛使用的開源Java分布式緩存。主要面向通用緩存,Java EE和輕量級容器。它具有內存和磁盤存儲,緩存加載器,緩存擴展,緩存異常處理程序,一個gzip緩存servlet過濾器,支持REST和SOAP api等特點。
它的一個缺點就是使用磁盤Cache的時候非常占用磁盤空間,這源于DiskCache的算法簡單,該算法簡單也導致Cache的效率非常高。它只是對元素直接追加存儲。因此搜索元素的時候非常的快。如果使用DiskCache的,在很頻繁的應用中,很快磁盤會滿。
另外一個問題是當突然kill掉java的時候,不能保證數據的安全,可能是產生沖突,Ehcache的解決方法是如果文件沖突了,則重建cache。這對于Cache數據需要保存的時候可能不利。當然,Cache只是簡單的加速,而不能保證數據的安全。如果想保證數據的存儲安全,可以使用Bekeley DB Java Edition版本。這是個嵌入式數據庫。可以確保存儲安全和空間的利用率。當然,還有很多的Cache。多數情況下,Ehcache能滿足常見需求。
二、使用實例
本文要使用
1、引入jar包
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.8.2</version> </dependency>
2、在classpath下增加ehcache配置文件 ehcache.xml與配置文件
設置控制ehcache的bean,這部分的內容也可以直接寫在spring的配置文件applicationContext.xml中去,這里為了方便管理,我給單獨寫出來了
beans-cache.xml
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd"> <cache:annotation-driven cache-manager="cacheManager" /> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="ehcache"></property> </bean> <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:beans/ehcache.xml"></property> </bean> </beans>
ehcache.xml設置緩存大小和時間,緩存空間名等。其中緩存空間可設置多個
<?xml version="1.0" encoding="UTF-8"?> <ehcache updateCheck="false"> <diskStore path="java.io.tmpdir" /> <!-- DefaultCache setting. --> <defaultCache eternal="false" overflowToDisk="false" diskPersistent="false" timeToLiveSeconds="36000" timeToIdleSeconds="36000" maxElementsInMemory="10000" memoryStoreEvictionPolicy="LRU"/> <!-- Special objects setting. --> <!-- Refresh sysParamCache every hour. --> <cache name="sysParamCache" overflowToDisk="false" eternal="false" diskPersistent="false" timeToLiveSeconds="36000" timeToIdleSeconds="36000" maxElementsInMemory="10000" memoryStoreEvictionPolicy="LRU"/> </ehcache>
參數說明:
<diskStore>:
當內存緩存中對象數量超過maxElementsInMemory時,將緩存對象寫到磁盤緩存中(需對象實現序列化接口)。
<diskStore path="">:
用來配置磁盤緩存使用的物理路徑,Ehcache磁盤緩存使用的文件后綴名是*.data和*.index。
name:
緩存名稱,cache的唯一標識(ehcache會把這個cache放到HashMap里)。
maxElementsOnDisk:
磁盤緩存中最多可以存放的元素數量,0表示無窮大。
maxElementsInMemory:
內存緩存中最多可以存放的元素數量,若放入Cache中的元素超過這個數值,則有以下兩種情況。
1)若overflowToDisk=true,則會將Cache中多出的元素放入磁盤文件中。
2)若overflowToDisk=false,則根據memoryStoreEvictionPolicy策略替換Cache中原有的元素。
Eternal:
緩存中對象是否永久有效,即是否永駐內存,true時將忽略timeToIdleSeconds和timeToLiveSeconds。
timeToIdleSeconds:
緩存數據在失效前的允許閑置時間(單位:秒),僅當eternal=false時使用,默認值是0表示可閑置時間無窮大,此為可選屬性即訪問這個cache中元素的最大間隔時間,若超過這個時間沒有訪問此Cache中的某個元素,那么此元素將被從Cache中清除。
timeToLiveSeconds:
緩存數據在失效前的允許存活時間(單位:秒),僅當eternal=false時使用,默認值是0表示可存活時間無窮大,即Cache中的某元素從創建到清楚的生存時間,也就是說從創建開始計時,當超過這個時間時,此元素將從Cache中清除。
overflowToDisk:
內存不足時,是否啟用磁盤緩存(即內存中對象數量達到maxElementsInMemory時,Ehcache會將對象寫到磁盤中),會根據標簽中path值查找對應的屬性值,寫入磁盤的文件會放在path文件夾下,文件的名稱是cache的名稱,后綴名是data。
diskPersistent:
是否持久化磁盤緩存,當這個屬性的值為true時,系統在初始化時會在磁盤中查找文件名為cache名稱,后綴名為index的文件,這個文件中存放了已經持久化在磁盤中的cache的index,找到后會把cache加載到內存,要想把cache真正持久化到磁盤,寫程序時注意執行net.sf.ehcache.Cache.put(Element element)后要調用flush()方法。
diskExpiryThreadIntervalSeconds:
磁盤緩存的清理線程運行間隔,默認是120秒。
diskSpoolBufferSizeMB:
設置DiskStore(磁盤緩存)的緩存區大小,默認是30MB
memoryStoreEvictionPolicy:
內存存儲與釋放策略,即達到maxElementsInMemory限制時,Ehcache會根據指定策略清理內存,共有三種策略,分別為LRU(最近最少使用)、LFU(最常用的)、FIFO(先進先出)。
3.spring配置文件 applicationContext.xml 添加ehcache的配置
<import resource="classpath:beans/beans-cache.xml" />
4.在service層增加注解配置
@Override @Cacheable(value="sysParamCache",key="#systemId+#merchantId+#businessType")// 使用了一個緩存名叫 accountCache public SettUnit getSettUnitBySettUnitId(String systemId, String merchantId, String businessType) {
key=#systemId+#merchantId+#businessType" 對象緩存的key值,需要保證唯一, 用的是Spring的 SpEL表達式, 取值為 isbn對象的id屬性值
value="sysParamCache":指的是ehcache.xml里的緩存名字
5、單元測試
@Test public void getSettUnitBySettUnitIdTest() { String systemId = "CES"; String merchantId = "133"; SettUnit configSettUnit = settUnitService.getSettUnitBySettUnitId(systemId, merchantId, "ESP"); SettUnit configSettUnit1 = settUnitService.getSettUnitBySettUnitId(systemId, merchantId, "ESP"); boolean flag= (configSettUnit == configSettUnit1); System.out.println(configSettUnit); logger.info("查找結果" + configSettUnit.getBusinessType()); // localSecondFIFOCache.put("configSettUnit", configSettUnit.getBusinessType()); // String string = localSecondFIFOCache.get("configSettUnit"); // logger.info("查找結果" + string); }
這是有緩存的結果,第二次直接從緩存中去取,比較兩個的地址,相等即表明兩上是同一個對象,第二次取的是第一次的結果
這是第一次取結果打印的SQL語句