SpringBoot詳解整合Spring?Cache實(shí)現(xiàn)Redis緩存流程
1、簡(jiǎn)介
Spring Cache 是一個(gè)框架,實(shí)現(xiàn)了基于注解的緩存功能,只需要簡(jiǎn)單地加一個(gè)注解,就能實(shí)現(xiàn)緩存功能。
Spring Cache 提供了一層抽象,底層可以切換不同的cache實(shí)現(xiàn)。
具體就是通過(guò) CacheManager 接口來(lái)統(tǒng)一不同的緩存技術(shù)。
CacheManager 是 Spring 提供的各種緩存技術(shù)抽象接口,這是默認(rèn)的緩存技術(shù),是緩存在Map中的,這也說(shuō)明當(dāng)服務(wù)掛掉的時(shí)候,緩存的數(shù)據(jù)就沒(méi)了。
針對(duì)不同的緩存技術(shù)需要實(shí)現(xiàn)不同的 CacheManager
CacheManager | 描述 |
---|---|
EhCacheCacheManager | 使用 EhCache 作為緩存技術(shù) |
GuavaCacheManager | 使用 Google 的 GuavaCache 作為緩存技術(shù) |
RedisCacheManager | 使用 Redis 作為緩存技術(shù) |
2、常用注解
在 Spring Boot 項(xiàng)目中,使用緩存技術(shù)只需在項(xiàng)目中導(dǎo)入相關(guān)緩存技術(shù)的依賴包,并在啟動(dòng)類上使用 @EnableCaching
開啟緩存支持即可。例如,使用 Redis 作為緩存技術(shù),只需要導(dǎo)入 Spring data Redis 的 maven 坐標(biāo)即可。常用的注解有如下幾個(gè):
注解 | 說(shuō)明 |
---|---|
@EnableCaching | 開啟緩存注解功能 |
@Cacheable | 在方法執(zhí)行前 spring 先查看緩存中是否有數(shù)據(jù),如果有數(shù)據(jù),則直接返回緩存數(shù)據(jù);若沒(méi)有數(shù)據(jù),調(diào)用方法并將方法返回值放到緩存中 |
@CachePut | 將方法的返回值放到緩存中 |
@CacheEvict | 將一條或多條數(shù)據(jù)從緩存中刪除 |
2.1、@EnableCaching
該注解的主要功能就是開啟緩存注解的功能,讓 Spring Cache 中的其他注解生效。使用方式也十分簡(jiǎn)單,直接將其加在項(xiàng)目的啟動(dòng)類上方即可。
@Slf4j @SpringBootApplication @EnableCaching public class CacheDemoApplication { public static void main(String[] args) { SpringApplication.run(CacheDemoApplication.class, args); log.info("項(xiàng)目啟動(dòng)成功..."); } }
2.2、@Cacheable
@Cacheable
注解主要是在方法執(zhí)行前 先查看緩存中是否有數(shù)據(jù)。如果有數(shù)據(jù),則直接返回緩存數(shù)據(jù);若沒(méi)有數(shù)據(jù),調(diào)用方法并將方法返回值放到緩存中。
注解中的參數(shù)傳遞主要使用的是**SpEL(Spring Expression Language)**對(duì)數(shù)據(jù)進(jìn)行獲取傳遞,這有點(diǎn)類似于JSP中的EL表達(dá)式,常用方式如下幾種:
- “#p0”:獲取參數(shù)列表中的第一個(gè)參數(shù)。其中的“#p”為固定寫法,0為下標(biāo),代表第一個(gè);
- “#root.args[0]”:獲取方法中的第一個(gè)參數(shù)。其中0為下標(biāo),代表第一個(gè)。
- “#user.id”:獲取參數(shù) user 的 id 屬性。注意的是這里的 user 必須要和參數(shù)列表中的參數(shù)名一致
- “#result.id”:獲取返回值中的 id 屬性。
來(lái)自Spring Cache源碼:Spring Expression Language (SpEL) expression used for making the method
在@Cacheable
注解中有幾種常用的屬性可進(jìn)行需求性設(shè)置:
- value:緩存的名稱,每個(gè)緩存名稱下面可以有多個(gè) key
- key:緩存的key。
- condition:條件判斷,滿足條件時(shí)對(duì)數(shù)據(jù)進(jìn)行緩存,值得注意的是該參數(shù)在Redis中無(wú)效
- unless:條件判斷,滿足條件時(shí)則不對(duì)數(shù)據(jù)進(jìn)行緩存,Redis中可使用該參數(shù)替代condition
/** * @description 通過(guò)id獲取用戶信息 * @author xBaozi * @date 14:23 2022/7/3 **/ @Cacheable(value = "userCache", key = "#id", unless = "#result == null") @GetMapping("/{id}") public User getById(@PathVariable Long id) { User user = userService.getById(id); return user; }
2.3、@CachePut
@CachPut
注解主要是將方法的返回值放到緩存中。這里同樣是使用SpEL獲取數(shù)據(jù),常用的屬性如下:
- value:緩存的名稱,每個(gè)緩存名稱下面可以有多個(gè) key
- key:緩存的key。
- condition:條件判斷,滿足條件時(shí)對(duì)數(shù)據(jù)進(jìn)行緩存,值得注意的是該參數(shù)在Redis中無(wú)效
- unless:條件判斷,滿足條件時(shí)則不對(duì)數(shù)據(jù)進(jìn)行緩存,Redis中可使用該參數(shù)替代condition
/** * @description 新增用戶信息并返回保存的信息 * @author xBaozi * @date 14:38 2022/7/3 **/ @CachePut(value = "userCache", key = "#user.id") @PostMapping public User save(User user) { userService.save(user); return user; }
2.4、@CacheEvict
@CacheeEvict
主要是將一條或多條數(shù)據(jù)從緩存中刪除,同樣使用SpEL獲取數(shù)據(jù),常用的屬性如下:
- value:緩存的名稱,每個(gè)緩存名稱下面可以有多個(gè) key
- key:緩存的key。
- condition:條件判斷,滿足條件時(shí)對(duì)數(shù)據(jù)進(jìn)行緩存,值得注意的是該參數(shù)在Redis中無(wú)效
- unless:條件判斷,滿足條件時(shí)則不對(duì)數(shù)據(jù)進(jìn)行緩存,Redis中可使用該參數(shù)替代condition
/** * @description 更新用戶信息 * @author xBaozi * @date 14:41 2022/7/3 **/ @CacheEvict(value = "userCache", key = "#result.id") @PutMapping public User update(User user) { userService.updateById(user); return user; }
3、使用Redis當(dāng)作緩存產(chǎn)品
因?yàn)?Spring 默認(rèn)的緩存技術(shù)無(wú)法持久化保存緩存數(shù)據(jù),即服務(wù)掛了緩存也掛了,因此就需要使用Redis進(jìn)行操作(其實(shí)也是因?yàn)閷W(xué)習(xí)了Redis)
前面的SpringBoot整合Redis緩存驗(yàn)證碼里面有記錄著一些Redis的基本操作。
3.1、坐標(biāo)導(dǎo)入
導(dǎo)入 maven 坐標(biāo):spring-boot-starter-data-redis、spring-boot-starter-cache
<!--Spring Data Redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!--Spring Cache--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
3.2、yml配置
spring:
redis:
host: localhost
port: 6379
password: 123456
database: 0
cache:
redis:
time-to-live: 1800000 # 設(shè)置緩存有效期
3.3、開啟注解功能
在啟動(dòng)類 com/itheima/CacheDemoApplication.java
上加入 @EnableCaching 注解,開啟緩存注解功能
@Slf4j @SpringBootApplication @ServletComponentScan @EnableCaching public class ReggieApplication { public static void main(String[] args) { SpringApplication.run(ReggieApplication.class, args); log.info("springBoot項(xiàng)目啟動(dòng)成功……"); } }
3.4、使用@Cacheable
這里提一下有個(gè)坑就是使用的緩存時(shí),返回值必須實(shí)現(xiàn) Serializable 序列化接口,否則將會(huì)報(bào)錯(cuò)。
這是因?yàn)樵?NoSql 數(shù)據(jù)庫(kù)中,并沒(méi)有與我們 Java 基本類型對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu),所以在往 NoSql 數(shù)據(jù)庫(kù)中存儲(chǔ)時(shí),我們就必須將對(duì)象進(jìn)行序列化,同時(shí)在網(wǎng)絡(luò)傳輸中我們要注意到兩個(gè)應(yīng)用中 javabean 的 serialVersionUID 要保持一致,不然就不能正常的進(jìn)行反序列化。
/** * @description 新增套餐信息 * @author xBaozi * @date 17:55 2022/5/13 * @param setmealDto 需要新增套餐的數(shù)據(jù) **/ @CacheEvict(value = "setmealCache",allEntries = true) @PostMapping public Result<String> save(@RequestBody SetmealDto setmealDto) { log.info("套餐信息為{}", setmealDto); setmealService.saveWithDish(setmealDto); return Result.success("套餐" + setmealDto.getName() + "新增成功"); }
3.5、使用@CacheEvict
這里用到了一個(gè)新屬性allEntries,其是boolean類型,表示是否需要清除緩存中的所有元素。默認(rèn)為false,表示不需要。當(dāng)指定了 allEntries 為 true 時(shí),Spring Cache將忽略指定的 key。有的時(shí)候我們需要 Cache 一下清除所有的元素,這比一個(gè)一個(gè)清除元素更有效率。
/** * @description 更新套餐信息并更新其關(guān)聯(lián)的菜品 * @author xBaozi * @date 11:28 2022/5/14 * @param setmealDto 需要更新的套餐信息 **/ @CacheEvict(value = "setmealCache",allEntries = true) @PutMapping public Result<String> updateWithDish(@RequestBody SetmealDto setmealDto) { log.info(setmealDto.toString()); setmealService.updateWithDish(setmealDto); return Result.success("套餐修改成功"); }
4、測(cè)試
代碼編寫完成之后,重啟工程,然后訪問(wèn)后臺(tái)管理系統(tǒng),對(duì)套餐數(shù)據(jù)進(jìn)行新增以及刪除,而后觀察Redis中的數(shù)據(jù)發(fā)現(xiàn)寫的代碼是能正常跑到!成功!
到此這篇關(guān)于SpringBoot詳解整合Spring Cache實(shí)現(xiàn)Redis緩存流程的文章就介紹到這了,更多相關(guān)SpringBoot Redis緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)視頻時(shí)間維度剪切的工具類
這篇文章主要為大家詳細(xì)介紹了將視頻按照時(shí)間維度進(jìn)行剪切的Java工具類,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12淺談Java由于不當(dāng)?shù)膱?zhí)行順序?qū)е碌乃梨i
為了保證線程的安全,我們引入了加鎖機(jī)制,但是如果不加限制的使用加鎖,就有可能會(huì)導(dǎo)致順序死鎖(Lock-Ordering Deadlock)。本文將會(huì)討論一下順序死鎖的問(wèn)題。2021-06-06Java基礎(chǔ)詳解之集合框架工具Collections
這篇文章主要介紹了Java基礎(chǔ)詳解之集合框架工具Collections,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下2021-04-04Spring注解實(shí)現(xiàn)Bean自動(dòng)裝配示例詳解
這篇文章主要給大家介紹了關(guān)于Spring注解實(shí)現(xiàn)Bean自動(dòng)裝配的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03MyBatis自定義TypeHandler如何解決字段映射問(wèn)題
這篇文章主要介紹了MyBatis自定義TypeHandler如何解決字段映射問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12使用Spirng Boot Admin監(jiān)控Spring Cloud應(yīng)用項(xiàng)目
這篇文章主要介紹了使用Spirng Boot Admin監(jiān)控Spring Cloud應(yīng)用項(xiàng)目,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05