Springboot redisson 自定義注解實現雙寫一致性

在 Spring Boot 項目中使用 Redisson 實現雙寫一致性(即數據庫和緩存的一致性),可以通過自定義注解和 AOP(面向切面編程)來簡化代碼并提高可維護性。以下是一個具體的案例,展示了如何使用自定義注解和 AOP 來實現這一目標。

實現步驟

1.添加依賴

首先,確保你的項目中包含了 Redisson 和 Spring Boot 的依賴。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><!-- Redisson -->
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.16.3</version>
</dependency>

2.配置 Redisson

在?application.yml?中配置 Redisson 客戶端連接到 Redis 服務器。

spring:redis:host: localhostport: 6379redisson:singleServerConfig:address: redis://${spring.redis.host}:${spring.redis.port}

3.添加配置類:

@Configuration
public class RedissonConfig {@Value("${redisson.singleServerConfig.address}")private String redisAddress;@Bean(destroyMethod = "shutdown")public RedissonClient redissonClient() {Config config = new Config();config.useSingleServer().setAddress(redisAddress);return Redisson.create(config);}
}

?4.自定義注解

創建一個自定義注解,另一個注解還用上篇的

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CustomerCacheEvict {/*** 緩存名稱* @return*/String key() default "";
}

5.AOP 切面

創建一個切面類?CustomCacheAspect,使用 Redisson 的讀寫鎖來實現緩存和數據庫的一致性。

@Aspect
@Component
public class CustomCacheAspect {@Resourceprivate RedisTemplate<String, Object> redisTemplate;@Resourceprivate RedissonClient redissonClient;@Around("@annotation(customCacheable)")public Object cache(ProceedingJoinPoint joinPoint, CustomCacheable customCacheable) throws Throwable {Object result;String key = customCacheable.key();long expireTime = customCacheable.expireTime();//獲取參數值key = getKey(joinPoint, key);// 加鎖RLock rLock = redissonClient.getReadWriteLock(key+":lock").readLock();rLock.lock();try {// 嘗試從緩存中獲取數據Object cachedValue = redisTemplate.opsForValue().get(key);if (cachedValue != null) {return cachedValue;}// 讀鎖升級為寫鎖,執行數據庫查詢操作    rLock.unlock();RLock wLock = redissonClient.getReadWriteLock(key + ":lock").writeLock();wLock.lock();try {// 再次檢查緩存,避免在獲取寫鎖期間,其他線程已填充緩存cachedValue = redisTemplate.opsForValue().get(key);if (cachedValue != null) {return cachedValue; // 直接返回緩存值}// 如果緩存中沒有數據,則執行方法并將結果存入緩存result = joinPoint.proceed();// 設置緩存if(expireTime > 0){redisTemplate.opsForValue().set(key, result, expireTime, TimeUnit.SECONDS);}else{redisTemplate.opsForValue().set(key, result);}}finally{if(wLock.isHeldByCurrentThread()) {wLock.unlock();}}}finally{if(rLock.isHeldByCurrentThread()){rLock.unlock();}}return result;}@Around("@annotation(customerCacheEvict)")public Object cache(ProceedingJoinPoint joinPoint, CustomerCacheEvict customerCacheEvict) throws Throwable {Object result;String key = customerCacheEvict.key();//獲取參數值key = getKey(joinPoint, key);// 加鎖RLock wLock = redissonClient.getReadWriteLock(key + ":lock").writeLock();wLock.lock();try {result = joinPoint.proceed();try {Thread.sleep(100);}catch (Exception e){e.printStackTrace();}redisTemplate.delete(key);}finally{if(wLock.isHeldByCurrentThread()){wLock.forceUnlock();}}return result;}/*** 獲取參數值* @return*/private String getKey(ProceedingJoinPoint joinPoint, String key) {Object[] args = joinPoint.getArgs();// 構建緩存鍵if (args != null && args.length > 0) {key = key + ":" + args[0];}return key;}
}

6.服務類

在接口類中使用自定義注解。(實際加到service 層更好)

    /*** 根據id查詢*/@GetMapping("/{id}")@CustomCacheable(key = "user")public  UserTest getById(@PathVariable Long id) {return userTestService.getById(id);}/*** 修改*/@PutMapping("/{id}")@CustomerCacheEvict(key="user")public boolean update(@PathVariable Integer id, @RequestBody UserTest userTest) {userTest.setId(id);return userTestService.updateById(userTest);}

通過以上步驟,我們使用自定義注解和 AOP 確保了數據庫和 Redis 緩存之間的一致性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/44839.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/44839.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/44839.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java研學-Shiro安全框架(四)

六 SpringBoot集成Shiro認證 1 分析 Shiro提供認證授權功能&#xff0c;所以SpringBoot中不需再編寫自定義注解&#xff0c;權限攔截&#xff0c;登錄攔截&#xff0c;登錄登出。Shiro 環境中有三個封裝對象Subject &#xff0c;SecurityManager和Realms&#xff0c;SpringBoo…

Java核心技術【二十一】Java的I/O流處理:文件的讀寫操作

Java的I/O流處理&#xff1a;文件讀寫操作 【創作】 不易&#xff0c;【點贊】 是情義&#xff0c;【關注】 是動力&#xff0c;【收藏】 是回憶。 示例代碼地址&#xff1a;https://gitee.com/code-in-java/csdn-blog.git 在Java編程中&#xff0c;輸入/輸出&#xff08;I/O&a…

PyTorch實現BERT預訓練模型轉化指南

huggingface官方的介紹&#xff1a; https://huggingface.co/transformers/converting_tensorflow_models.html 直接用命令行 把箭頭處路徑改為自己放原有tf版本預訓練模型的路徑 回車后會有一大堆提示&#xff0c;然后發現路徑下多了一個bin文件&#xff0c;加上原本的config…

順序結構 ( 六 ) —— 順序結構實例 【互三互三】

&#x1f680;歡迎互三&#x1f449;&#xff1a;程序猿方梓燚 &#x1f48e;&#x1f48e;&#x1f680;所屬專欄&#xff1a;C教程&#x1f48e; &#x1f680;關注博主&#xff0c;后期持續更新系列文章 &#x1f680;如果有錯誤感謝請大家批評指出&#xff0c;及時修改 &am…

iNavFlight飛控固件學習-1《開發環境搭建》

目錄 文章目錄 目錄摘要1.官網2.形成Linux開發環境工具2.1 簡介2.2 相關工具2.2.1 Ubuntu / Debian系統配置命令2.2.2 Fedora系統配置命令2.2.3 Fedora系統配置命令 2.3 克隆存儲庫2.4 構建工具2.5 使用cmake2.6 構建固件2.7 清除2.8 cmake 緩存維護2.9 編譯通過ninja2.10 更新…

js 日期比較大小

在JavaScript中&#xff0c;比較日期大小通常涉及將日期轉換為時間戳&#xff08;自1970年1月1日以來的毫秒數&#xff09;&#xff0c;然后比較這些時間戳。這是因為直接比較兩個Date對象可能不會按預期工作&#xff0c;特別是如果你試圖了解哪個日期在另一個日期之前或之后。…

紅酒與未來科技:傳統與創新的碰撞

在歲月的長河中&#xff0c;紅酒以其深邃的色澤、豐富的口感和不同的文化魅力&#xff0c;成為人類文明中的一顆璀璨明珠。而未來科技&#xff0c;則以其迅猛的發展速度和無限的可能性&#xff0c;領著人類走向一個嶄新的時代。當紅酒與未來科技相遇&#xff0c;一場傳統與創新…

2024.07.03校招 實習 內推 面經

綠*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;內推/實習/校招匯總表格 1、提前批 | 中國兵器工業集團第二〇二研究所 | 提前批/招/聘暨/暑期/開放日 提前批 | 中國兵器工業集團第二〇二研究所 | 提前批招聘暨暑期開放日 2、夏令營 | 2024年南網數字集團“未來…

ADI新型充電器解決方案可實現電池堆電壓和充電效率

就目前而言&#xff0c;這可能是生活中zui常見的問題了。世紀之交&#xff0c;電池&#xff08;尤其是基于鋰離子的電池&#xff09;成本的降低和性能的提高&#xff0c;推動了電池供電的儲能和便攜式設備的穩步增長。此外&#xff0c;超級電容器由于具有獨特的性質&#xff0c…

oppo25屆秋招,快手25屆技術人才專項計劃內推

oppo25屆秋招&#xff0c;快手25屆技術人才專項計劃內推 ①【OPPO】25屆秋招開啟&#xff01; 內推簡歷優先篩選&#xff01; &#x1f449;崗位類別&#xff1a;AI/算法類&#xff0c;軟件類&#xff0c;硬件類&#xff0c;工程技術類&#xff0c;品牌策劃類&#xff0c;設計類…

骨傳導耳機最熱門好用款推薦,選購骨傳導耳機前不能忽略的六大細節

如今的社會在耳機種類方面可以說是越來越多&#xff0c;于是很多人在挑選的時候往往選擇不到適合自己的一款耳機&#xff0c;尤其是在近些年來席卷耳機市場的骨傳導耳機&#xff0c;開放耳道的設計在很多時候佩戴無異于是更加的適合&#xff0c;正好小編這邊對于比較熱門的幾款…

社交App iOS審核中的4.3問題:深入分析與解決策略

社交App審核中的4.3問題&#xff1a;深入分析與解決策略 在iOS應用開發和審核過程中&#xff0c;開發者經常會遇到蘋果審核4.3問題。這一問題往往涉及應用的設計和內容重復性&#xff0c;導致應用被拒絕上架。為了幫助開發者更好地理解和解決這一問題&#xff0c;本文將對4.3問…

動漫3d模型設計需要注意什么?---模大獅模型網

設計動漫3D模型時&#xff0c;有幾個方面需要注意&#xff1a; 保持角色風格一致性&#xff1a; 動漫通常有獨特的風格和美學&#xff0c;設計時要確保模型與所代表的角色或作品的整體風格相符。注意保持線條和比例的一致性&#xff0c;使模型能夠忠實地呈現原作的特點。 注重…

springboot餐飲管理系統-計算機畢業設計源碼43667

摘 要 在信息化、數字化的時代背景下&#xff0c;餐飲行業面臨著前所未有的挑戰與機遇。為了提高運營效率、優化顧客體驗&#xff0c;餐飲企業亟需一套高效、穩定且靈活的管理系統來支撐其日常運營。基于Spring Boot的餐飲管理系統應運而生&#xff0c;成為餐飲行業數字化轉型的…

Python基礎教學之一:入門篇——邁入編程世界的第一步

Python基礎教學之一&#xff1a;入門篇——邁入編程世界的第一步 一、Python簡介&#xff1a;歷史與現狀 Python&#xff0c;一種解釋型、高級和通用的編程語言&#xff0c;由Guido van Rossum在1989年圣誕節期間創造&#xff0c;并于1991年首次發布。設計哲學強調代碼的可讀性…

論文降痕降重全攻略:從技巧到工具,助你輕松應對學術挑戰

AIGC降重工具&#xff1a;快速降低論文查重率 高查重率是許多畢業生的困擾。通常&#xff0c;高查重率源于過度引用未經修改的參考資料和格式錯誤。傳統的降重方法&#xff0c;如修改文本和增添原創內容&#xff0c;雖必要但耗時且成效不一。 鑒于此&#xff0c;應用AI工具進…

【企業級監控】源碼部署Zabbix與監控主機

Zabbix企業級分布式監控 文章目錄 Zabbix企業級分布式監控資源列表基礎環境一、LNMP環境搭建&#xff08;在zbx主機上&#xff09;1.1、配置Yum倉庫1.1.1、下載阿里云的倉庫文件1.2.2、安裝PHP7的倉庫1.2.3、生成Mariadb10.11的倉庫文件1.2.4、快速重建Yum緩存 1.2、安裝PHP7.4…

請求取消(多種)

XMLHttpRequest XMLHttpRequest 可以使用 abort() 方法來實現請求取消。 const xhr new XMLHttpRequest();xhr.open(GET, http://localhost:3000/api/txt);xhr.timeout 2;xhr.ontimeout function () {xhr.abort();console.error(請求超時&#xff0c;已中斷);};xhr.onload …

shell腳本之for循環

一、循環中的常見語句 1.1 echo 打印 -n &#xff1a;表示不換行輸出-e &#xff1a;輸出轉義字符 \b &#xff1a;相當于退格鍵(backspace)\n &#xff1a;換行&#xff0c;相當于回車\f &#xff1a;換行&#xff0c;換行后的新行的開頭連著上一行的行尾\t &#xff1a;插入…

編程用什么軸體比較好用:全面解析四種軸體的優劣與應用

編程用什么軸體比較好用&#xff1a;全面解析四種軸體的優劣與應用 在編程的世界里&#xff0c;選擇一款合適的機械鍵盤軸體&#xff0c;不僅能提升工作效率&#xff0c;更能帶來舒適的打字體驗。然而&#xff0c;面對市場上琳瑯滿目的軸體類型&#xff0c;究竟該如何選擇呢&a…