Spring Boot 使用 AOP 防止重複提交

2021-09-23 14:31:57 字數 1956 閱讀 8854

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

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

自定義註解 @norepeatsubmit 標記所有controller中的提交請求

通過aop 對所有標記了 @norepeatsubmit 的方法攔截

在業務方法執行前,獲取當前使用者的 token(或者jsessionid)+ 當前請求位址,作為乙個唯一 key,去獲取 redis

分布式鎖(如果此時併發獲取,只有乙個執行緒會成功獲取鎖)

業務方法執行後,釋放鎖

關於redis 分布式鎖

使用redis 是為了在負載均衡部署,如果是單機的部署的專案可以使用乙個執行緒安全的本地cache 替代 redis

code

@aspect

@component

public class repeatsubmitaspect

@around("pointcut()")

public object before(proceedingjoinpoint pjp) ], clientid = [{}]", key, clientid);

if (issuccess) ], clientid = [{}]", key, clientid);

// 獲取鎖成功, 執行程序

object result = pjp.proceed();

// 解鎖

redislock.releaselock(key, clientid);

logger.info("releaselock success, key = [{}], clientid = [{}]", key, clientid);

return result;

} else ]", key);

return new apiresult(200, "重複請求,請稍後再試", null);

}} catch (throwable throwable)

return new apiresult(500, "系統異常", null);

}private string getkey(string token, string path)

private string getclientid()

}

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

@component

private static final logger logger = logge***ctory.getlogger(runtest.class);

@autowired

private resttemplate resttemplate;

@override

system.out.println("執行多執行緒測試");

}

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

Springboot如何使用AOP

切面的包 1 springboot 不自帶aop 需要自己新增依賴 org.springframework.bootgroupid spring boot starter aopartifactid dependency 2 直接 aspect寫切面類就行了1 連線點 可以理解為需要被增強的方法 2...

Spring Boot 之優雅使用 AOP

aop為aspect oriented programming的縮寫,意思是面向切面程式設計,通過預編譯的方式和執行時動態 實現程式功能的統一維護的一種技術。利用aop可以對業務邏輯進行分離,降低耦合度,提高可重用性,提高開發效率。主要用途 日誌記錄 事務處理 異常處理 安全處理 效能統計 在spr...

Springboot 中AOP的使用

面向切面程式設計 aspect oriented programming 是軟體程式設計思想發展到一定階段的產物,是物件導向程式設計的有益補充。aop一般適用於具有橫切邏輯的場合,如訪問控制 事務管理 效能檢測等。日誌 異常處理 事務控制等都是乙個健壯的業務系統所必須的。但是為了保證系統健壯可用,就...