SpringBoot ehcache 緩存
簡介
EhCache 是一個純 Java 的進程內(nèi)緩存框架,具有快速、精干等特點穗泵,
是 Hibernate 中默認CacheProvider瓮孙。Ehcache 是一種廣泛使用的開源 Java 分布式緩存。
主要面向通用緩存,Java EE 和輕量級容器麸祷。它具有內(nèi)存和磁盤存儲澎怒,緩存加載器,緩存擴展,緩存異常處理程序,一個 gzip 緩存 servlet 過濾器,支持 REST 和 SOAP api 等特點。
特性
- 快速阶牍、簡單
- 多種緩存策略
- 緩存數(shù)據(jù)有兩級:內(nèi)存和磁盤喷面,因此無需擔(dān)心容量問題
- 緩存數(shù)據(jù)會在虛擬機重啟的過程中寫入磁盤
- 可以通過RMI、可插入API等方式進行分布式緩存
- 具有緩存和緩存管理器的偵聽接口
- 支持多緩存管理器實例走孽,以及一個實例的多個緩存區(qū)域
- 提供Hibernate的緩存實現(xiàn)
與 Redis 相比
- EhCache 直接在jvm虛擬機中緩存惧辈,速度快,效率高磕瓷;但是緩存共享麻煩盒齿,集群分布式應(yīng)用不方便。
- Redis 是通過 Socket 訪問到緩存服務(wù)困食,效率比 EhCache 低边翁,比數(shù)據(jù)庫要快很多,處理集群和分布式緩存方便陷舅,有成熟的方案倒彰。如果是單個應(yīng)用或者對緩存訪問要求很高的應(yīng)用,用 EhCache 莱睁。如果是大型系統(tǒng)待讳,存在緩存共享芒澜、分布式部署、緩存內(nèi)容很大的创淡,建議用 Redis痴晦。
- EhCache 也有緩存共享方案,不過是通過 RMI 或者 Jgroup 多播方式進行廣播緩存通知更新琳彩,緩存共享復(fù)雜誊酌,維護不方便;簡單的共享可以露乏,但是涉及到緩存恢復(fù)碧浊,大數(shù)據(jù)緩存,則不合適瘟仿。
相關(guān)配置
核心依賴文件
<!-- Spring Boot 緩存支持啟動器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Ehcache 坐標 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!-- diskStore 這個是磁盤存儲路徑箱锐,當內(nèi)存緩存滿了的時候,就會往這里面放劳较,java.io.tmdir是操作系統(tǒng)緩存的臨時目錄驹止,不同操作系統(tǒng)緩存目錄不一樣。-->
<diskStore path="java.io.tmpdir"/>
<!--defaultCache:echcache的默認緩存策略 -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
<!--以下為自定義的緩存策略 -->
<cache name="dictCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</cache>
</ehcache>
標簽說明
diskStore: <diskStore path="java.io.tmpdir"/>這個是磁盤存儲路徑观蜗,當內(nèi)存緩存滿了的時候臊恋,就會往這里面放,java.io.tmdir是操作系統(tǒng)緩存的臨時目錄墓捻,不同操作系統(tǒng)緩存目錄不一樣抖仅。
-
maxElementsInMemory: 內(nèi)存緩存中最多可以存放的元素數(shù)量,若放入Cache中的元素超過這個數(shù)值,則有以下兩種情況
- 若overflowToDisk=true,則會將Cache中多出的元素放入磁盤文件中
- 若overflowToDisk=false,則根據(jù)memoryStoreEvictionPolicy策略替換Cache中原有的元素
overflowToDisk : 內(nèi)存不足時,是否啟用磁盤緩存
eternal: 緩存中對象是否永久有效
timeToIdleSeconds: 緩存數(shù)據(jù)在失效前的允許閑置時間(單位:秒),僅當eternal=false時使用,默認值是0表示可閑置時間無窮大,若超過這個時間沒有訪問此Cache中的某個元素,那么此元素將被從Cache中清除
timeToLiveSeconds: 緩存數(shù)據(jù)的總的存活時間(單位:秒)毙替,僅當eternal=false時使用岸售,從創(chuàng)建開始計時,失效結(jié)束厂画。
maxElementsOnDisk: 磁盤緩存中最多可以存放的元素數(shù)量,0表示無窮大
diskExpiryThreadIntervalSeconds: 磁盤緩存的清理線程運行間隔,默認是120秒
memoryStoreEvictionPolicy: 內(nèi)存存儲與釋放策略,即達到maxElementsInMemory限制時,Ehcache會根據(jù)指定策略清理內(nèi)存 共有三種策略,分別為LRU(最近最少使用)、LFU(最常用的)拷邢、FIFO(先進先出)
application.xml
spring:
cache:
ehcache:
config: classpath:ehcache.xml
啟動類
加上以下注解
@EnableCaching
用法實例:
以下以業(yè)務(wù)字典作為demo演示袱院;
注意:待緩存的對象需要實現(xiàn) 可序列化接口Serializable;由于需要實體類支持緩存中的磁盤存儲瞭稼,所以需要實體類實現(xiàn)可序列化接口
@Data
public class SysDic implements Serializable {
//主鍵
private Integer dicId;
//業(yè)務(wù)場景編碼
private String busiSceneCode;
//字典編碼
private String dicCode;
//字典名稱
private String dicName;
//顯示順序
private Integer displayOrder;
//創(chuàng)建人
private String createStaff;
//創(chuàng)建時間
private Date createTime;
//最后修改時間
private Date lastModiTime;
//狀態(tài)(1有效 0無效)
private Integer status;
// 備注
private String remark;
}
數(shù)據(jù)緩存
@Cacheable(value = "dictCache", key = "#sysDic.busiSceneCode")
@Override
public IPage<SysDic> queryPage(Page<SysDic> page, SysDic sysDic) {
return this.baseMapper.selectPage(page, new QueryWrapper<SysDic>(sysDic));
}
@Cacheable 注解說明:
-
@Cacheable可以標記在一個方法或一個類上;
- 當標記在一個方法上時表示該方法是支持緩存的;
- 當標記在一個類上時則表示該類所有的方法都是支持緩存的忽洛。
-
@Cacheable可以指定三個屬性,value环肘、key和condition欲虚。
- value: 指定cache的名稱(即選擇ehcache.xml中哪種緩存方式存儲)
- key: 用來指定Spring緩存方法的返回結(jié)果時對應(yīng)的key的。該屬性支持SpringEL表達式悔雹。當我們沒有指定該屬性時复哆,Spring將使用默認策略生成key欣喧。我們也直接使用“#參數(shù)名”或者“#p參數(shù)index”.
@Cacheable 參數(shù)示例:
@Cacheable(value="dictCache", key="#id")
public SysDic find(Integer id) {
return null;
}
@Cacheable(value="dictCache", key="#p0")
public SysDic find(Integer id) {
return null;
}
@Cacheable(value="dictCache", key="#sysDic.id")
public SysDic find(SysDic sysDic) {
return null;
}
@Cacheable(value="dictCache", key="#p0.id")
public SysDic find(SysDic sysDic) {
return null;
}
清除緩存
@CacheEvict(value = "dictCache", allEntries = true)
public boolean insert(SysDic sysDic) {
return this.baseMapper.insert(sysDic) > 0 ? true : false;
}
@CacheEvict(value = "dictCache", allEntries = true)
@Override
public boolean updateDicById(SysDic sysDic) {
return this.baseMapper.updateById(sysDic) > 0 ? true : false;
}
@CacheEvict(value = "dictCache", allEntries = true)
@Override
public boolean deleteByDicId(List<Long> idList) {
return this.baseMapper.deleteBatchIds(idList) > 0 ? true : false;
}
@CacheEvict 注解說明
- @CacheEvict是用來標注在需要清除緩存元素的方法或類上的。 當標記在一個類上時表示其中所有的方法的執(zhí)行都會觸發(fā)緩存的清除操作梯找。
- @CacheEvict可以指定的屬性有value唆阿、key、condition锈锤、allEntries和beforeInvocation驯鳖。 其中value、key和condition的語義與@Cacheable對應(yīng)的屬性類似久免;allEntries是boolean類型浅辙,
表示是否需要清除緩存中的所有元素。默認為false阎姥,表示不需要记舆。 - 當指定了allEntries為true時,Spring Cache將忽略指定的key丁寄。有的時候我們需要Cache一下清除所有的元素氨淌,這比一個一個清除元素更有效率。