Spring Boot 使用 AOP 防止重複提交

作者:殷天文
來源:www.jianshu.com/p/09860b74658e

在傳統的web項目中,防止重複提交,通常做法是:後端生成一個唯一的提交令牌(uuid),並存儲在服務端。頁面提交請求攜帶這個提交令牌,後端驗證並在第一次驗證後刪除該令牌,保證提交請求的唯一性。

上述的思路其實沒有問題的,但是需要前後端都稍加改動,如果在業務開發完在加這個的話,改動量未免有些大了,本節的實現方案無需前端配合,純後端處理。

思路

  1. 自定義註解 @NoRepeatSubmit 標記所有Controller中的提交請求
  2. 通過AOP 對所有標記了 @NoRepeatSubmit 的方法攔截
  3. 在業務方法執行前,獲取當前用戶的 token(或者JSessionId)+ 當前請求地址,作為一個唯一 KEY,去獲取 Redis 分佈式鎖(如果此時併發獲取,只有一個線程會成功獲取鎖)
  4. 業務方法執行後,釋放鎖

關於Redis 分佈式鎖

不瞭解的同學戳這裡 ==> Redis分佈式鎖的正確實現方式

使用Redis 是為了在負載均衡部署,如果是單機的部署的項目可以使用一個線程安全的本地Cache 替代 Redis

Code

這裡只貼出 AOP 類和測試類,完整代碼:

https://github.com/TavenYin/taven-springboot-learning/tree/master/repeat-submit-intercept

Spring Boot 使用 AOP 防止重複提交

Spring Boot 使用 AOP 防止重複提交

多線程測試

測試代碼如下,模擬十個請求併發同時提交

Spring Boot 使用 AOP 防止重複提交

成功防止重複提交,控制檯日誌如下,可以看到十個線程的啟動時間幾乎同時發起,只有一個請求提交成功了

Spring Boot 使用 AOP 防止重複提交

本節demo

https://gitee.com/yintianwen7/taven-springboot-learning/tree/master/repeat-submit-intercept

build項目之後,啟動本地redis,運行項目自動執行測試方法

參考

https://www.jianshu.com/p/09c6b05b670a


分享到:


相關文章: