淺談SpringAOP

来源:https://www.cnblogs.com/wenbochang/archive/2019/01/24/10316900.html
-Advertisement-
Play Games

0. 寫在最前面 之前實習天天在寫業務,其中有一個業務是非常的複雜,涉及到了特別多的表。最後測下來,一個介面的時間,竟然要5s多。 當時想寫一個AOP,來計算處理介面花費多長時間,也就是在業務邏輯的前面計算開始的時間,業務邏輯後面計算結束的時間,一相減即可。 但我發覺我竟然忘記怎麼寫了,哎,沒辦法, ...


0. 寫在最前面

之前實習天天在寫業務,其中有一個業務是非常的複雜,涉及到了特別多的表。最後測下來,一個介面的時間,竟然要5s多。

當時想寫一個AOP,來計算處理介面花費多長時間,也就是在業務邏輯的前面計算開始的時間,業務邏輯後面計算結束的時間,一相減即可。

但我發覺我竟然忘記怎麼寫了,哎,沒辦法,在此紀錄,重新撿回吧。

 

1. 什麼AOP

AOP(Aspect-Oriented Programming, 面向切麵編程): 是一種新的方法論, 是對傳統 OOP(Object-Oriented Programming, 面向對象編程) 的補充.

AOP 的主要編程對象是切麵(aspect), 而切麵模塊化橫切關註點.

在應用 AOP 編程時, 仍然需要定義公共功能, 但可以明確的定義這個功能在哪裡, 以什麼方式應用, 並且不必修改受影響的類. 這樣一來橫切關註點就被模塊化到特殊的對象(切麵)里.

AOP 的好處: 每個事物邏輯位於一個位置, 代碼不分散, 便於維護和升級 業務模塊更簡潔, 只包含核心業務代碼.

簡單來說,AOP就是在不影響現有的業務邏輯下麵,在業務前面後面織入一些其他邏輯。比如,日誌,驗證等等

 

2. SpringAOP有哪幾種

  • @Before: 前置通知, 在方法執行之前執行

  • @After: 後置通知, 在方法執行之後執行

  • @AfterRunning: 返回通知, 在方法返回結果之後執行

  • @AfterThrowing: 異常通知, 在方法拋出異常之後

  • @Around: 環繞通知, 圍繞著方法執行

 

假設我們現在有一個介面如下:

1 @RequestMapping("/aa")
2 public String a() {
3     Person person = new Person("zhangsan", 18);
4     redisService.put("person", person);
5     Person ps = redisService.get("person");
6     return ps.toString();
7 }

 

現在產品提了一個需求,我想在這段業務執行前,列印一句話,結束後在列印一句話。

很簡單,我們直接改業務代碼就行了,一個可以兩個可以,但是多了呢,很嚴重影響業務邏輯,此時就可以用到了前置通知和後置通知。

 1 @Pointcut(value = "execution (public * com.test.mybatis.demo.web.DepartmentController.*(..))")
 2 public void pointCut() { }
 3 
 4 @Before(value = "pointCut()")
 5 public void beforeMethod(JoinPoint joinPoint) {
 6     String methodName = joinPoint.getSignature().getName();
 7     List<Object> args = Lists.newArrayList(joinPoint.getArgs());
 8     log.info("The method [" + methodName + "] begins with " + args);
 9 }
10 
11 @After(value = "pointCut()")
12 public void afterMethod(JoinPoint joinPoint) {
13     String methodName = joinPoint.getSignature().getName();
14     log.info("The method [" + methodName + "] ends");
15 }

 

解釋下這段代碼。

PointCut 簡稱切點,也就是一個表達式,我要在哪些介面上進行攔截,進行一個配置。他有他自己的一套規範,我們按照他的規範來就好了。

JoinPoint 簡稱連接點。程式執行的某個特定位置:如類某個方法調用前、調用後、方法拋出異常後等。JoinPoint 我可以獲取到方法名,參數等等。

@Before,@After 一個是前置通知,一個是後置通知

 此時我再訪問這個介面的時候,他的執行流程如下:

 beforeMethod  ==>  業務邏輯  ==>  afterMethod

是不是非常的神奇,AOP的實現方式可以看我這邊博文:動態代理兩種實現方式

 

 3. 回到我們的最初

如何計算一個介面耗時多少呢?

起初我想到可以用前置 + 後置 來做,但最後相減,變數怎麼傳遞不好搞。想過用全局變數,但併發會出現問題。

此時我想到了很少用的環繞通知,最後代碼如下:

 1 @Around("pointCut()")
 2 public Object aroundMethod(ProceedingJoinPoint joinPoint) {
 3     Object res = null;
 4     String methodName = joinPoint.getSignature().getName();
 5     try {
 6         // 前置通知
 7         Stopwatch stopwatch = Stopwatch.createStarted();
 8         // 執行目標方法
 9         res = joinPoint.proceed();
10         // 後置通知
11         long duration = stopwatch.elapsed(TimeUnit.MILLISECONDS);
12         log.info("{} 執行時長: {}", methodName, duration);
13     } catch (Throwable throwable) {
14         throwable.printStackTrace();
15     }
16     return res;
17 }

每次執行一個方法,他都會將你的執行時間列印出來。結果如下:

1 // 前置通知
2 2019-01-24 21:17:52.802  INFO 224 --- [nio-8080-exec-5] com.test.mybatis.demo.AOP.TestAOP        : The method [testAOP] begins
3 // 業務邏輯
4 這裡是業務邏輯
5 // 環繞通知
6 2019-01-24 21:17:53.303  INFO 224 --- [nio-8080-exec-5] com.test.mybatis.demo.AOP.TestAOP        : testAOP 執行時長: 500
7 // 後置通知
8 2019-01-24 21:17:53.303  INFO 224 --- [nio-8080-exec-5] com.test.mybatis.demo.AOP.TestAOP        : The method [testAOP] ends

 

4. 寫在最後

最後我想將這個計算介面時間的AOP定義成一個註解,只要我在介面上加這個註解,他就會列印時間,否則就不列印。

這是後期的一個目標。共勉

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 想要用Python的suds模塊調用webservice地址做自動測試,但是找了很多方法都失敗了,最終找到另外一個模塊可以作為客戶端訪問伺服器地址。 1.針對非安全的http 列印結果: { '_value_1': '{"errorMsg":"沒有找到路由信息!"}', 'id': None, 'h ...
  • 第75節:Java中的JSP,EL和JSTL 哭吧看不完的!!! 和`Session 請求轉發和重定向的區別: 1. 地址不一樣 2. 請求次數也不一樣 3. 數據無法傳遞 4.跳轉範圍有限制 5. 效率 請求轉發請求1次,只能對當前項目跳轉,重定向請求2次.重定向是無法傳遞的,重定向對跳轉範圍沒有 ...
  • python介紹 這是我們專門為 小白 量身打造的Python新手教程,具有如下特點: 全視頻,手把手,零起點,項目實例,基於船新的Python 版本 。 Python是一種電腦程式設計語言。你可能已經聽說過很多種流行的編程語言,比如非常難學的C語言,非常流行的Java語言,適合網頁編程的Java ...
  • 原文地址:https://blog.csdn.net/u012811805/article/details/80878848 1 jar啟動分離依賴lib和配置 先前發佈boot項目的時候,改動一點東西,就需要將整個項目重新打包部署,十分不便,故把依賴lib從項目分離出來,每次部署只需要發佈代碼即可 ...
  • 2019-01-24 22:30:32 記錄學習PAT的一些知識,有待更新 註:本文是對Algorithm 演算法筆記 的總結 C++標準庫模板(Standard Template Library,STL) 【vector】 1.單獨定義一個vector vector<typename> name; ...
  • 今天小編為大家準備了4本Python入門書籍,讓大家在python的學習路上少走彎路。 1.Python基礎教程 《Python基礎教程》是經典的Python入門教程書籍,本書層次鮮明,結構嚴謹,特別是在最後幾章中,作者將前面講述的內容應用到項目中,並以模板的形式介紹了項目的開發過程,手把手教授Py ...
  • 遞歸 一個函數在執行過程中一次或多次調用其本身便是遞歸,就像是俄羅斯套娃一樣,一個娃娃里包含另一個娃娃。 遞歸其實是程式設計語言學習過程中很快就會接觸到的東西,但有關遞歸的理解可能還會有一些遺漏,下麵對此方面進行更加深入的理解 遞歸的分類 這裡根據遞歸調用的數量分為線性遞歸、二路遞歸與多重遞歸 線性 ...
  • 背景介紹 JSF(京東服務框架,類似dubbo)預設配置了可伸縮的最大到200的工作線程池,每一個向外提供的服務都在其中運行(這裡我們是服務端),這些服務內部調用外部依賴時(這裡我們是客戶端)一般是同步調用,不單獨限制調用併發量,因為同步調用時會阻塞原服務線程,因此實際上所有外部調用共用了JSF的2 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...