spring框架中的本地緩存之spring cache基本使用詳解
基本概念及原理
處理邏輯
Spring Cache 是 Spring 提供的一整套的緩存解決方案。
雖然它本身并沒(méi)有提供緩存的實(shí)現(xiàn),但是它提供了一整套的接口和代碼規(guī)范、配置、注解等,這樣它就可以整合各種緩存方案了
處理邏輯:
每次調(diào)用某方法,而此方法又是帶有緩存功能時(shí),Spring 框架就會(huì)檢查指定參數(shù)的那個(gè)方法是否已經(jīng)被調(diào)用過(guò),如果之前調(diào)用過(guò),就從緩存中取之前調(diào)用的結(jié)果;如果沒(méi)有調(diào)用過(guò),則再調(diào)用一次這個(gè)方法,并緩存結(jié)果,然后再返回結(jié)果,那下次調(diào)用這個(gè)方法時(shí),就可以直接從緩存中獲取結(jié)果了。
實(shí)現(xiàn)步驟
SpringCache實(shí)現(xiàn)步驟 :
啟用緩存 :通過(guò) @EnableCaching 注解觸發(fā) Spring 的緩存代理配置
。AOP 攔截
:Spring 為標(biāo)記注解的方法生成代理對(duì)象,在方法調(diào)用前后插入緩存操作。緩存處理
:根據(jù)注解配置,調(diào)用 CacheManager 獲取 Cache 實(shí)例,執(zhí)行讀寫(xiě)或刪除操作。
核心原理
Spring Cache 的核心原理基于 AOP(面向切面編程) 和 緩存抽象
,通過(guò)注解簡(jiǎn)化緩存邏輯的集成。
其核心是 緩存抽象層 和 動(dòng)態(tài)代理機(jī)制
,結(jié)合 Spring Boot 的自動(dòng)配置,可快速集成多種緩存方案,顯著提升系統(tǒng)性能
Spring Cache 通過(guò) 抽象層 解耦具體緩存技術(shù):
適配器模式
:通過(guò) CacheManager 和 Cache 接口適配不同緩存實(shí)現(xiàn)(如 Redis、Ehcache)。自動(dòng)配置
:Spring Boot 的 spring-boot-autoconfigure 模塊自動(dòng)檢測(cè)并配置緩存實(shí)現(xiàn)(如引入 spring-boot-starter-data-redis 后自動(dòng)啟用 Redis 緩存)。
核心組件與抽象
Cache 接口 :定義緩存操作(如 get、put、evict)
,具體實(shí)現(xiàn)由第三方緩存技術(shù)(如 Redis、Caffeine)提供。
CacheManager 接口 :管理多個(gè) Cache 實(shí)例,負(fù)責(zé)創(chuàng)建、配置和獲取緩存對(duì)象
。
例如:
ConcurrentMapCacheManager(默認(rèn)內(nèi)存緩存)RedisCacheManager(Redis 實(shí)現(xiàn))EhCacheCacheManager(Ehcache 實(shí)現(xiàn))
核心注解
Spring 提供了五個(gè)注解來(lái)聲明緩存規(guī)則。
@Cacheable:方法執(zhí)行前檢查緩存,命中則直接返回,否則執(zhí)行方法并緩存結(jié)果。
@CachePut:方法調(diào)用前不會(huì)去緩存中查找,無(wú)論緩存是否存在,都執(zhí)行方法并更新緩存。
@CacheEvict:刪除指定緩存,清除緩存中的一條或多條記錄
@Caching:組合多個(gè)緩存操作。
@CacheConfig:在類級(jí)別共享相同的緩存的配置
注解 | 作用 | 常用參數(shù) |
---|---|---|
@Cacheable | 方法結(jié)果緩存(先查緩存,未命中執(zhí)行方法),一般用在查詢方法上 | value, key, condition |
@CachePut | 強(qiáng)制更新緩存(始終執(zhí)行方法),一般用在新增方法上 | value, key, unless |
@CacheEvict | 清除緩存,一般用在更新或者刪除方法上 | value, key, allEntries |
@Caching | 組合多個(gè)緩存操作,實(shí)現(xiàn)同一個(gè)方法上同時(shí)使用多種注解 | cacheable, put, evict |
@CacheConfig | 類級(jí)別共享緩存配置 | cacheNames, keyGenerator |
SpEL 表達(dá)式
場(chǎng)景 | 表達(dá)式示例 |
---|---|
防緩存穿透 | unless = “#result == null” |
多字段復(fù)合鍵 | key = “#user.id + ‘:’ + #user.deviceId” |
時(shí)間戳動(dòng)態(tài)鍵 | key = “T(System).currentTimeMillis()” |
權(quán)限過(guò)濾 | condition = “#authLevel > 3” |
集合非空判斷 | condition = “!#list.isEmpty()” |
實(shí)現(xiàn)
pom依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
選擇使用的緩存
# 使用redis進(jìn)行緩存 spring.cache.type=redis
Spring Cache 支持很多緩存中間件作為框架中的緩存,總共有 9 種選擇:
- caffeine:Caffeine 是一種高性能的緩存庫(kù),基于 Google Guava。
- couchbase:CouchBase是一款非關(guān)系型JSON文檔數(shù)據(jù)庫(kù)。
- generic:由泛型機(jī)制和 static 組合實(shí)現(xiàn)的泛型緩存機(jī)制。
- hazelcast:一個(gè)高度可擴(kuò)展的數(shù)據(jù)分發(fā)和集群平臺(tái),可用于實(shí)現(xiàn)分布式數(shù)據(jù)存儲(chǔ)、數(shù)據(jù)緩存。
- infinispan:分布式的集群緩存系統(tǒng)。
- jcache:JCache 作為緩存。它是 JSR107 規(guī)范中提到的緩存規(guī)范。
- none:沒(méi)有緩存。
- redis:用 Redis 作為緩存
- simple:用內(nèi)存作為緩存
基本概念
在啟動(dòng)類上面添加@EnableCaching注解
指定某方法開(kāi)啟緩存功能。在方法上添加 @Cacheable 緩存注解就可以了。
@Cacheable 注解中,可以添加四種參數(shù):value,key,condition,unless
- value:指定緩存名稱(必填)
- key:自定義緩存鍵(SpEL表達(dá)式)
- condition:執(zhí)行前條件判斷(SpEL)
- unless:執(zhí)行后結(jié)果過(guò)濾(SpEL)
參數(shù) | 類型 | 作用 | 示例 |
---|---|---|---|
value | String[] | 指定緩存名稱(必填) | value = “users” 或 value = {“cache1”, “cache2”} |
key | String | 自定義緩存鍵(SpEL表達(dá)式) | key = "#userId"或key = “T(java.util.UUID).randomUUID().toString()” |
condition | String | 執(zhí)行前條件判斷(SpEL) | condition = "#userId > 1000"或condition = “#name.startsWith(‘admin’)” |
unless | String | 執(zhí)行后結(jié)果過(guò)濾(SpEL) | unless = "#result == null"或unless = “#result.age < 18” |
使用示例1
第一次調(diào)用下面這個(gè)接口前,緩存里面是沒(méi)有hot緩存,也沒(méi)有這個(gè)test方法的結(jié)果緩存
調(diào)用test方法后,緩存中便會(huì)創(chuàng)建出hot這個(gè)緩存,其中緩存了一個(gè)key(默認(rèn)值SimpleKey[]),其中有一個(gè)值
- 緩存中 key 對(duì)應(yīng)的 value 默認(rèn)使用 JDK 序列化后的數(shù)據(jù)。
- value 的過(guò)期時(shí)間為 -1,表示永不過(guò)期。
key:hot:SimpleKey[]
value:222
@RequestMapping("/test2") @Cacheable({"hot"}) public int test() { return 222; }
第二次調(diào)用test()方法時(shí),便會(huì)直接讀緩存,而不去執(zhí)行test里面的方法
@RequestMapping("/test2") @Cacheable({"hot"}) public int test2() { return 456; }
如果再將類名改為test2后,緩存獲取到的值還是test方法時(shí)緩存的值222,因?yàn)閮蓚€(gè)方法的key值都是SimpleKey[]
使用示例2
// 啟用緩存(配置類) @EnableCaching @Configuration public class CacheConfig { @Bean public CacheManager cacheManager() { return new ConcurrentMapCacheManager("users"); // 內(nèi)存緩存 } } // 業(yè)務(wù)層使用 @Service public class UserService { // 緩存讀?。╲alue=緩存名稱,key=緩存鍵) @Cacheable(value = "users", key = "#userId") public User getUserById(Long userId) { // 實(shí)際數(shù)據(jù)庫(kù)查詢 return userRepository.findById(userId); } // 緩存更新 @CachePut(value = "users", key = "#user.id") public User updateUser(User user) { return userRepository.save(user); } // 緩存清除 @CacheEvict(value = "users", key = "#userId") public void deleteUser(Long userId) { userRepository.deleteById(userId); } }
自定義配置類
自定義緩存過(guò)去時(shí)間等
# 使用 Redis 作為緩存組件 spring.cache.type=redis # 緩存過(guò)期時(shí)間為 3600s spring.cache.redis.time-to-live=3600000 # 緩存的鍵的名字前綴 spring.cache.redis.key-prefix=passjava_ # 是否使用緩存前綴 spring.cache.redis.use-key-prefix=true # 是否緩存控制,防止緩存穿透 spring.cache.redis.cache-null-values=true
自定義 key
在 @Cacheable 注解里面加上 key 的值 #root.method.name。這是一種特有的表達(dá)式,稱作 SpEL 表達(dá)式,這里代表用方法名作為緩存 key 的名字
@Cacheable(value = {"hot"}, key = "#root.method.name")
如果按上述去配置的話,緩存的key的名稱便是這個(gè)方法名
自定義條件
可以自定義條件來(lái)決定是否將緩存功能關(guān)閉。這里就要用到@Cacheable 另外兩個(gè)屬性:condition 和 unless,它倆的格式還是用 SpEL 表達(dá)式
到此這篇關(guān)于spring框架中的本地緩存:spring cache基本使用的文章就介紹到這了,更多相關(guān)spring cache使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot緩存抽象@Cacheable與緩存管理器配置方法
- Java實(shí)現(xiàn)本地緩存的四種方案(Guava Cache、Caffeine、Ehcach 和Spring Cache)
- SpringBoot集成Redis使用Cache緩存的實(shí)現(xiàn)方法
- 使用Spring Cache和Redis實(shí)現(xiàn)查詢數(shù)據(jù)緩存
- 在SpringBoot項(xiàng)目中使用JetCache緩存的詳細(xì)教程
- Spring Cache自定義緩存key和過(guò)期時(shí)間的實(shí)現(xiàn)代碼
- Spring @Cacheable自定義緩存過(guò)期時(shí)間的實(shí)現(xiàn)示例
- Springboot集成Ehcache3實(shí)現(xiàn)本地緩存的配置方法
- spring @Cacheable擴(kuò)展實(shí)現(xiàn)緩存自動(dòng)過(guò)期時(shí)間及自動(dòng)刷新功能
相關(guān)文章
Spring Boot+Mybatis+Pagehelper分頁(yè)實(shí)現(xiàn)
本篇文章主要講述的是Spring Boot+Mybatis+Pagehelper分頁(yè)實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Springboot項(xiàng)目瘦身之如何將jar包與lib依賴分開(kāi)打包
這篇文章主要介紹了Springboot項(xiàng)目瘦身之如何將jar包與lib依賴分開(kāi)打包問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04Java利用條件運(yùn)算符的嵌套來(lái)完成學(xué)習(xí)成績(jī)的劃分
這篇文章主要介紹了Java利用條件運(yùn)算符的嵌套來(lái)完成學(xué)習(xí)成績(jī)的劃分,需要的朋友可以參考下2017-02-02詳解使用Spring的BeanPostProcessor優(yōu)雅的實(shí)現(xiàn)工廠模式
這篇文章主要介紹了詳解使用Spring的BeanPostProcessor優(yōu)雅的實(shí)現(xiàn)工廠模式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07Java中的鍵盤(pán)事件處理及監(jiān)聽(tīng)機(jī)制解析
這篇文章主要介紹了Java中的鍵盤(pán)事件處理及監(jiān)聽(tīng)機(jī)制解析,Java事件處理采用了委派事件模型,在這個(gè)模型中,當(dāng)事件發(fā)生時(shí),產(chǎn)生事件的對(duì)象將事件信息傳遞給事件的監(jiān)聽(tīng)者進(jìn)行處理,在Java中,事件源是產(chǎn)生事件的對(duì)象,比如窗口、按鈕等,需要的朋友可以參考下2023-10-10Springboot文件上傳功能的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot文件上傳功能的實(shí)現(xiàn),文中通過(guò)代碼示例介紹的非常詳細(xì),具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們可以參考閱讀2023-04-04Eclipse項(xiàng)目有紅感嘆號(hào)的解決方法
這篇文章主要為大家詳細(xì)介紹了Eclipse項(xiàng)目有紅感嘆號(hào)的解決方法,給出了Eclipse項(xiàng)目有紅感嘆號(hào)的原因,以及如何解決?,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04java反射之Method的invoke方法實(shí)現(xiàn)教程詳解
這篇文章主要給大家介紹了關(guān)于java反射之Method的invoke方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01