說明
Spring Cache是Spring架構的緩存抽象,內建了各種主流緩存實作(ConcurrentMap、redis、ehcache、Caffeine等)
Spring預設使用ConcurrentMap作為緩存;如果工程中引入了redis配置,則會使用redis作為緩存
Spring通過CacheManager判斷具體使用哪個緩存,每個緩存都有一個具體的CacheManager(比如:EhCacheCacheManager,RedisCacheManager,CaffeineCacheManager),如果沒有配置任何的CacheManager,則會使用ConcurrentMap作為緩存
常用注解說明
SpEL表達式說明
注解中key的寫法是SpEL表達式,
Spring Cache提供了一些供我們使用的SpEL上下文資料,下表直接摘自Spring官方文檔:
說明:
1、當我們要使用root對象的屬性作為key時我們也可以将“#root”省略,因為Spring預設使用的就是root對象的屬性。如:
@Cacheable(key = "targetClass + methodName +#p0")
2、使用方法參數時我們可以直接使用“#參數名”或者“#p參數index”。如:
@Cacheable(value="users", key="#id")
@Cacheable(value="users", key="#p0")
SpEL提供了多種運算符
在工程中使用
1、引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
2、在工程中配置
在啟動類中增加注解 @EnableCaching 開啟緩存功能
在application.properties中添加可選自定義配置
詳細配置項可參考(org.springframework.boot.autoconfigure.cache.CacheProperties)
3、在代碼中使用
1)儲存時,緩存傳回值
@CachePut(value="dict",key="targetClass +'AppDictType'+ #entity.dictTypeCd")
@Transactional(readOnly = false)
public AppDictType save(AppDictType entity) {
return dictTypeDao.save(entity);
}
2)查詢時,先讀取緩存,如果緩存不存在,則執行方法查詢,然後更新緩存
@Cacheable(value="dict",key="targetClass +'AppDictType'+ #dictTypeCd")
public AppDictType findByDictTypeCd(String dictTypeCd) {
return dictTypeDao.findByDictTypeCd(dictTypeCd);
}
3)删除時,清空緩存
@Transactional(readOnly = false)
@CacheEvict(value="dict",key="targetClass +'AppDictType'+ #dictTypeCd")
public void deleteByDictTypeCd(String dictTypeCd) {
dictTypeDao.deleteByDictTypeCd(dictTypeCd);
}
4)測試用例
@Test
public void testCache() {
String dictTypeCd = "test01";
AppDictType entity = new AppDictType();
entity.setDictTypeCd(dictTypeCd);
entity.setDictTypeName("測試01");
// 新增記錄,并放入緩存
entity = dictService.save(entity);
// 查詢緩存
AppDictType dict = dictService.findByDictTypeCd(dictTypeCd);
logger.info("dict1:{}", JsonUtil.obj2Json(dict));
// 修改資料
entity.setDictTypeName("測試0011");
entity = dictService.save(entity);
// 查詢緩存,資料發生變化
AppDictType dict2 = dictService.findByDictTypeCd(dictTypeCd);
logger.info("dict2:{}", JsonUtil.obj2Json(dict3));
// 删除記錄,并清除緩存
dictService.deleteByDictTypeCd(dictTypeCd);
// 查詢記錄為空
AppDictType dict3 = dictService.findByDictTypeCd(dictTypeCd);
logger.info("dict3:{}", JsonUtil.obj2Json(dict4));
}
4、使用redis緩存
1)引入redis依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2)在application.properties 配置redis連結參數
spring.redis.host=192.168.1.144
spring.redis.port=6379
5、使用ehcache緩存
1)引入ehcache依賴
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
2)在application.properties 配置redis連結參數
#可以強制指定,也可以不指定,系統會自動偵測
#spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:ehcache.xml
3)增加ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!--當ehcache把資料寫到硬碟上時,将寫到這個目錄下,java.io.tmpdir:為預設臨時檔案路徑-->
<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="fileConfig"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</cache>
<!--
緩存配置說明:
name:緩存名稱。
maxElementsInMemory:緩存最大對象個數。
eternal:對象是否永久有效,一但設定了,timeout将不起作用。
timeToIdleSeconds:設定對象在失效前的允許閑置時間(機關:秒)。僅當eternal=false對象不是永久有效時使用,可選屬性,預設值是0,也就是可閑置時間無窮大。
timeToLiveSeconds:設定對象在失效前允許存活時間(機關:秒)。最大時間介于建立時間和失效時間之間。僅當eternal=false對象不是永久有效時使用,預設是0.,也就是對象存活時間無窮大。
overflowToDisk:當記憶體中對象數量達到maxElementsInMemory時,Ehcache将會對象寫到磁盤中。
diskSpoolBufferSizeMB:這個參數設定DiskStore(磁盤緩存)的緩存區大小。預設是30MB。每個Cache都應該有自己的一個緩沖區。
maxElementsOnDisk:硬碟最大緩存個數。
diskPersistent:是否緩存虛拟機重新開機期資料 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds:磁盤失效線程運作時間間隔,預設是120秒。
memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache将會根據指定的政策去清理記憶體。預設政策是LRU(最近最少使用)。你可以設定為FIFO(先進先出)或是LFU(較少使用)。
clearOnFlush:記憶體數量最大時是否清除。
-->
</ehcache>
4)在方法中指定cacheName
@Cacheable("fileConfig")
public SysFileConfig findByAppCode(String appCode) {
SysFileConfig config = fileConfigDao.selectOne(new QueryWrapper<SysFileConfig>().eq("app_code", appCode));
return config;
}
5、關閉spring cache緩存
如果已經開啟了@EnableCaching緩存,在某些環境下又不想使用緩存,又不想修改原有代碼。
可通過如下配置關閉緩存:
spring.cache.type=none
參考
- https://www.cnblogs.com/yueshutong/p/9381540.html
- https://docs.spring.io/spring-boot/docs/2.2.0.RELEASE/reference/htmlsingle/#boot-features-caching