SpringBoot ehcache 緩存
簡介
EhCache 是一個純 Java 的進程內緩存框架,具有快速、精幹等特點,
是 Hibernate 中默認CacheProvider。Ehcache 是一種廣泛使用的開源 Java 分佈式緩存。
主要面向通用緩存,Java EE 和輕量級容器。它具有內存和磁盤存儲,緩存加載器,緩存擴展,緩存異常處理程序,一個 gzip 緩存 servlet 過濾器,支持 REST 和 SOAP api 等特點。
特性
- 快速、簡單
- 多種緩存策略
- 緩存數據有兩級:內存和磁盤,因此無需擔心容量問題
- 緩存數據會在虛擬機重啓的過程中寫入磁盤
- 可以通過RMI、可插入API等方式進行分佈式緩存
- 具有緩存和緩存管理器的偵聽接口
- 支持多緩存管理器實例,以及一個實例的多個緩存區域
- 提供Hibernate的緩存實現
與 Redis 相比
- EhCache 直接在jvm虛擬機中緩存,速度快,效率高;但是緩存共享麻煩,集羣分佈式應用不方便。
- Redis 是通過 Socket 訪問到緩存服務,效率比 EhCache 低,比數據庫要快很多,處理集羣和分佈式緩存方便,有成熟的方案。如果是單個應用或者對緩存訪問要求很高的應用,用 EhCache 。如果是大型系統,存在緩存共享、分佈式部署、緩存內容很大的,建議用 Redis。
- EhCache 也有緩存共享方案,不過是通過 RMI 或者 Jgroup 多播方式進行廣播緩存通知更新,緩存共享複雜,維護不方便;簡單的共享可以,但是涉及到緩存恢復,大數據緩存,則不合適。
相關配置
核心依賴文件
<!-- 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 這個是磁盤存儲路徑,當內存緩存滿了的時候,就會往這裏面放,java.io.tmdir是操作系統緩存的臨時目錄,不同操作系統緩存目錄不一樣。-->
<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"/>這個是磁盤存儲路徑,當內存緩存滿了的時候,就會往這裏面放,java.io.tmdir是操作系統緩存的臨時目錄,不同操作系統緩存目錄不一樣。
-
maxElementsInMemory: 內存緩存中最多可以存放的元素數量,若放入Cache中的元素超過這個數值,則有以下兩種情況
- 若overflowToDisk=true,則會將Cache中多出的元素放入磁盤文件中
- 若overflowToDisk=false,則根據memoryStoreEvictionPolicy策略替換Cache中原有的元素
overflowToDisk : 內存不足時,是否啓用磁盤緩存
eternal: 緩存中對象是否永久有效
timeToIdleSeconds: 緩存數據在失效前的允許閒置時間(單位:秒),僅當eternal=false時使用,默認值是0表示可閒置時間無窮大,若超過這個時間沒有訪問此Cache中的某個元素,那麼此元素將被從Cache中清除
timeToLiveSeconds: 緩存數據的總的存活時間(單位:秒),僅當eternal=false時使用,從創建開始計時,失效結束。
maxElementsOnDisk: 磁盤緩存中最多可以存放的元素數量,0表示無窮大
diskExpiryThreadIntervalSeconds: 磁盤緩存的清理線程運行間隔,默認是120秒
memoryStoreEvictionPolicy: 內存存儲與釋放策略,即達到maxElementsInMemory限制時,Ehcache會根據指定策略清理內存 共有三種策略,分別爲LRU(最近最少使用)、LFU(最常用的)、FIFO(先進先出)
application.xml
spring:
cache:
ehcache:
config: classpath:ehcache.xml
啓動類
加上以下註解
@EnableCaching
用法實例:
以下以業務字典作爲demo演示;
注意:待緩存的對象需要實現 可序列化接口Serializable;由於需要實體類支持緩存中的磁盤存儲,所以需要實體類實現可序列化接口
@Data
public class SysDic implements Serializable {
//主鍵
private Integer dicId;
//業務場景編碼
private String busiSceneCode;
//字典編碼
private String dicCode;
//字典名稱
private String dicName;
//顯示順序
private Integer displayOrder;
//創建人
private String createStaff;
//創建時間
private Date createTime;
//最後修改時間
private Date lastModiTime;
//狀態(1有效 0無效)
private Integer status;
// 備註
private String remark;
}
數據緩存
@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緩存方法的返回結果時對應的key的。該屬性支持SpringEL表達式。當我們沒有指定該屬性時,Spring將使用默認策略生成key。我們也直接使用“#參數名”或者“#p參數index”.
@Cacheable 參數示例:
@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是用來標註在需要清除緩存元素的方法或類上的。 當標記在一個類上時表示其中所有的方法的執行都會觸發緩存的清除操作。
- @CacheEvict可以指定的屬性有value、key、condition、allEntries和beforeInvocation。 其中value、key和condition的語義與@Cacheable對應的屬性類似;allEntries是boolean類型,
表示是否需要清除緩存中的所有元素。默認爲false,表示不需要。 - 當指定了allEntries爲true時,Spring Cache將忽略指定的key。有的時候我們需要Cache一下清除所有的元素,這比一個一個清除元素更有效率。