AOP案例(黑馬學習筆記)

需求

需求:將案例中增、刪、改相關接口的操作日志記錄到數據庫表中

? ? ● 就是當訪問部門管理和員工管理當中的增、刪、改相關功能接口時,需要詳細的操作日志,并保存在數據表中,便于后期數據追蹤。

操作日志信息包含:

? ? ● 操作人、操作時間、執行方法的全類名、執行方法名、方法運行時參數、返回值、方法執行時長

所記錄的日志信息包括當前接口的操作人是誰操作的,什么時間點操作的,以及訪問的是哪個類當中的哪個方法,在訪問這個方法的時候傳入進來的參數是什么,訪問這個方法最終拿到的返回值是什么,以及整個接口方法的運行時長是多長時間。

分析

問題1:項目當中增刪改相關的方法是不是有很多?

? ??●?很多

問題2:我們需要針對每一個功能接口方法進行修改,在每一個功能接口當中都來記錄這些操作日志嗎?

? ??●?這種做法比較繁瑣

以上兩個問題的解決方案:可以使用AOP解決(每一個增刪改功能接口中要實現的記錄操作日志的邏輯代碼是相同)。

可以把這部分記錄操作日志的通用的、重復性的邏輯代碼抽取出來定義在一個通知方法當中,我們通過AOP面向切面編程的方式,在不改動原始功能的基礎上來對原始的功能進行增強。目前我們所增強的功能就是來記錄操作日志,所以也可以使用AOP的技術來實現。使用AOP的技術來實現也是最為簡單,最為方便的。

問題3:既然要基于AOP面向切面編程的方式來完成的功能,那么我們要使用 AOP五種通知類型當中的哪種通知類型?

? ??●?答案:環繞通知

所記錄的操作日志當中包括:操作人、操作時間,訪問的是哪個類、哪個方法、方法運行時參數、方法的返回值、方法的運行時長。

方法返回值,是在原始方法執行后才能獲取到的。

方法的運行時長,需要原始方法運行之前記錄開始時間,原始方法運行之后記錄結束時間。通過計算獲得方法的執行耗時。

基于以上的分析我們確定要使用Around環繞通知。

問題4:最后一個問題,切入點表達式我們該怎么寫?

答案:使用annotation來描述表達式

要匹配業務接口當中所有的增刪改的方法,而增刪改方法在命名上沒有共同的前綴或后綴。此時如果使用execution切入點表達式也可以,但是會比較繁瑣。 當遇到增刪改的方法名沒有規律時,就可以使用 annotation切入點表達式

步驟

簡單分析了一下大概的實現思路后,接下來我們就要來完成案例了。案例的實現步驟其實就兩步:

? ??●?準備工作

? ? ? ? 1.引入AOP的起步依賴

? ? ? ? 2.導入數據庫表結構,并引入對應的實體類

? ??●?編碼實現

? ? ? ? 1.自定義注解@Log

? ? ? ? 2.定義切面類,完成記錄操作日志的邏輯

實現

準備工作

1.AOP起步依賴

<!--AOP起步依賴-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.導入數據庫表結構,并引入對應的實體類

數據表

-- 操作日志表
create table operate_log(id int unsigned primary key auto_increment comment 'ID',operate_user int unsigned comment '操作人',operate_time datetime comment '操作時間',class_name varchar(100) comment '操作的類名',method_name varchar(100) comment '操作的方法名',method_params varchar(1000) comment '方法參數',return_value varchar(2000) comment '返回值',cost_time bigint comment '方法執行耗時, 單位:ms'
) comment '操作日志表';

實體類

//操作日志實體類
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OperateLog {private Integer id; //主鍵IDprivate Integer operateUser; //操作人IDprivate LocalDateTime operateTime; //操作時間private String className; //操作類名private String methodName; //操作方法名private String methodParams; //操作方法參數private String returnValue; //操作方法返回值private Long costTime; //操作耗時
}

Mapper接口

@Mapper
public interface OperateLogMapper {//插入日志數據@Insert("insert into operate_log (operate_user, operate_time, class_name, method_name, method_params, return_value, cost_time) " +"values (#{operateUser}, #{operateTime}, #{className}, #{methodName}, #{methodParams}, #{returnValue}, #{costTime});")public void insert(OperateLog log);}

編碼實現

? ? ● 自定義注解@Log

/*** 自定義Log注解*/
@Target({ElementType.METHOD})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
}

? ??●?修改業務實現類,在增刪改業務方法上添加@Log注解

@Slf4j
@Service
public class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;@Override@Logpublic void update(Emp emp) {emp.setUpdateTime(LocalDateTime.now()); //更新修改時間為當前時間empMapper.update(emp);}@Override@Logpublic void save(Emp emp) {//補全數據emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());//調用添加方法empMapper.insert(emp);}@Override@Logpublic void delete(List<Integer> ids) {empMapper.delete(ids);}//省略其他代碼...
}

以同樣的方式,修改EmpServiceImpl業務類

? ??●?定義切面類,完成記錄操作日志的邏輯

@Slf4j
@Component
@Aspect //切面類
public class LogAspect {@Autowiredprivate HttpServletRequest request;@Autowiredprivate OperateLogMapper operateLogMapper;@Around("@annotation(com.itheima.anno.Log)")public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable {//操作人ID - 當前登錄員工ID//獲取請求頭中的jwt令牌, 解析令牌String jwt = request.getHeader("token");Claims claims = JwtUtils.parseJWT(jwt);Integer operateUser = (Integer) claims.get("id");//操作時間LocalDateTime operateTime = LocalDateTime.now();//操作類名String className = joinPoint.getTarget().getClass().getName();//操作方法名String methodName = joinPoint.getSignature().getName();//操作方法參數Object[] args = joinPoint.getArgs();String methodParams = Arrays.toString(args);long begin = System.currentTimeMillis();//調用原始目標方法運行Object result = joinPoint.proceed();long end = System.currentTimeMillis();//方法返回值String returnValue = JSONObject.toJSONString(result);//操作耗時Long costTime = end - begin;//記錄操作日志OperateLog operateLog = new OperateLog(null,operateUser,operateTime,className,methodName,methodParams,returnValue,costTime);operateLogMapper.insert(operateLog);log.info("AOP記錄操作日志: {}" , operateLog);return result;}}

代碼實現細節: 獲取request對象,從請求頭中獲取到jwt令牌,解析令牌獲取出當前用戶的id。

重啟SpringBoot服務,測試操作日志記錄功能:

? ??●?添加一個新的部門

? ? ● 數據表

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

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

相關文章

IO多路轉接

1.select 初識select 系統提供 select 函數來實現多路復用輸入 / 輸出模型 . select 系統調用是用來讓我們的程序監視多個文件描述符的狀態變化的 ; 程序會停在 select 這里等待&#xff0c;直到被監視的文件描述符有一個或多個發生了狀態改變 ; select函數模型 select的函…

服務器硬件得基礎知識介紹

服務器硬件是計算機硬件的一種&#xff0c;專門用于構建服務器系統。服務器硬件通常具有高性能、高可靠性和可擴展性等特點&#xff0c;以滿足企業級應用的需求。本文將從以下幾個方面介紹服務器硬件的基礎知識&#xff1a;服務器概述、CPU、內存、存儲、網絡、電源和散熱、服務…

【機器學習】CIFAR-10數據集簡介、下載方法(自動)

【機器學習】CIFAR-10數據集簡介、下載方法(自動) &#x1f308; 個人主頁&#xff1a;高斯小哥 &#x1f525; 高質量專欄&#xff1a;Matplotlib之旅&#xff1a;零基礎精通數據可視化、Python基礎【高質量合集】、PyTorch零基礎入門教程&#x1f448; 希望得到您的訂閱和支…

0904多元復合函數求導-多元函數微分法及其應用

文章目錄 1 復習一元函數復合函數求導2 一元函數與多元函數復合的情形3 多元函數與多元函數復合的情形4 其他情形5 抽象復合函數求導6 全微分不變性結語 1 復習一元函數復合函數求導 y f ( u ) , u ? ( x ) ? f [ ? ( x ) ] d y d x d y d u ? d u d x f ′ ( u ) ? ?…

Python正則表達式:從基礎到高級應用的全面總結與實戰【第103篇—JSON模塊】

Python正則表達式&#xff1a;從基礎到高級應用的全面總結與實戰 正則表達式是一種強大的文本匹配和處理工具&#xff0c;廣泛應用于文本處理、數據抽取、表單驗證等領域。本文將從正則表達式的基礎知識出發&#xff0c;逐步深入&#xff0c;最終結合代碼實戰&#xff0c;帶你…

趙文彬將出席無磷鍋爐工藝助劑在鍋爐水節水節能應用

演講嘉賓&#xff1a;趙文彬 集團副總/技術總監 上遠未來水務集團有限公司 演講題目&#xff1a;無磷鍋爐工藝助劑在鍋爐水節水節能方面的應用 會議簡介 “十四五”規劃中提出&#xff0c;提高工業、能源領城智能化與信息化融合&#xff0c;明確“低碳經濟”新的戰略目標&a…

mac 安裝hbuilderx

下載 HBuilderX下載地址: 下載地址 選額mac版本點擊下載 安裝 如圖&#xff0c;將HBuilderX拖到Applications&#xff0c;才是正確的安裝姿勢。 MacOSX&#xff0c;軟件必須安裝到/Applications目錄&#xff0c;如未安裝到此目錄&#xff0c;可能會出現插件安裝失敗、項目創建…

基于BERTopic模型的中文文本主題聚類及可視化

文章目錄 BERTopic簡介模型加載地址文本加載數據處理BERTopic模型構建模型結果展示主題可視化總結BERTopic簡介 BERTopic論文地址:BERTopic: Neural topic modeling with a class-based TF-IDF procedure BERTopic是一種結合了預訓練模型BERT和主題建模的強大工具。它允許我…

Linux中的動靜態庫

目錄 一、靜態庫 &#xff08;1&#xff09;靜態庫的優缺點&#xff1a; &#xff08;2&#xff09;Linux下靜態庫的創建和執行 1.直接編譯?編輯 2.指定路徑和庫名 3.用LIBRARY_PATH環境變量來配置路徑 二、動態庫 &#xff08;1&#xff09;動態庫的優缺點 &#xff…

javaweb請求與響應

前言 前面介紹了對應的服務器端的相關代碼。這里開始學習服務器端與客戶端的數據請求與響應 這里的僅僅是一個簡單的調用&#xff0c;并沒有經過servelert接口來進行調用&#xff0c;同前面的一樣&#xff0c;我們介紹對應的本地服務器進行的部署項目。 代碼 //屬于簡單的不…

Java學習—線程的創建

Java 中的多線程是一種強大的機制&#xff0c;允許程序同時執行兩個或兩個以上的部分。這些同時執行的部分被稱為線程&#xff0c;它們可以使程序的執行更加高效&#xff0c;特別是在進行大量計算或等待資源&#xff08;比如網絡資源或文件系統&#xff09;時。Java 提供了在程…

Scratch 第十三課-飛機大戰游戲

第十三課-飛機大戰游戲 學習目標 這節課我們做一款大家都愛玩的飛機大戰游戲&#xff0c;學習重點&#xff1a; 如何導入外部角色如何讓飛機發射子彈鼠標控制角色移動 程序設計 程序分析 &#xff1a; 飛機大戰游戲相信很多小朋友都玩過&#xff0c;我方飛機在下方&#xf…

LabVIEW石油鉆機提升系統數字孿生技術

LabVIEW石油鉆機提升系統數字孿生技術 隨著數字化、信息化、智能化的發展&#xff0c;石油鉆采過程中的石油鉆機數字化技術提升成為了提高鉆井效率、降低生產成本的重要途徑。基于中石油云平臺提供的數據&#xff0c;采用數字孿生技術&#xff0c;對石油鉆機提升系統進行數字化…

[Redis]——初識Redis

一、Redis為非關系型數據庫 ?我們常見的MySQL、SQLServer都是關系型數據庫&#xff0c;那他們之間有什么區別與聯系呢&#xff1f; &#x1f4d5;關系型數據庫與非關系型數據庫的區別&#xff08;面試題&#xff09; 解釋&#xff1a; SQL數據庫中的表是有結構的&#xff0c;包…

騰訊云學生云服務器_學生云主機_學生云數據庫_云+校園特惠套餐

2024年騰訊云學生服務器優惠活動「云校園」&#xff0c;學生服務器優惠價格&#xff1a;輕量應用服務器2核2G學生價30元3個月、58元6個月、112元一年&#xff0c;輕量應用服務器4核8G配置191.1元3個月、352.8元6個月、646.8元一年&#xff0c;CVM云服務器2核4G配置842.4元一年&…

小程序和頁面生命周期詳解

目錄 小程序的生命周期 創建&#xff08;onLoad&#xff09;&#xff1a; 顯示&#xff08;onShow&#xff09;&#xff1a; 隱藏&#xff08;onHide&#xff09;&#xff1a; 卸載&#xff08;onUnload&#xff09;&#xff1a; 錯誤監聽&#xff08;onError&#xff09;…

JVM 第二部分-2(堆,方法區)

4.堆 堆 一個Java程序&#xff08;main方法&#xff09;對應一個jvm實例&#xff0c;一個jvm實例只有一個堆空間堆是jvm啟動的時候就被創建&#xff0c;大小也確定了。大小可以用參數設置。堆是jvm管理的一塊最大的內存空間 核心區域&#xff0c;是垃圾回收的重點區域堆可以位…

洛谷P1509找啊找啊找GF

題解&#xff1a;這題我們需要考慮兩個因素 &#xff0c;既要有錢&#xff0c;也需要有人品&#xff0c;但是呢&#xff0c;還想花最少得時間泡到最多的女生&#xff0c;那么這題我們就要用到以往的二維dp數組&#xff0c;但是真的是二維的嗎&#xff1f;不&#xff0c;因為要考…

如何讓大項目自動化測試更加靈活簡潔

如何把大象放到冰箱里&#xff1f;第一打開冰箱門&#xff0c;第二把大象放進去&#xff0c;第三把冰箱門關好。 這個問題言外之意是大象那么大&#xff0c;怎么能放進冰箱&#xff0c;為什么要把大象放冰箱&#xff0c;就開始糾結這個問題了&#xff0c;它是想表明不用太多糾結…

Day20-磁盤管理

Day20-磁盤管理 1. cut 切:2. 磁盤歷史和內外部物理結構介紹2.1 磁盤發展趨勢和實現措施2.2 磁盤知識的體系結構2.3 機械磁盤的外部結構2.4 SSD固態硬盤的外部結構2.5 固態硬盤內部結構2.6 緩存在服務器各硬件上的速度和大小對比另類維度圖解&#xff0c;從上到下由高速到低速&…