深入理解Spring AOP的工作流程

文章目錄

    • 引言
    • 什么是AOP?
    • Spring AOP的工作原理
      • 1. JDK動態代理
      • 2. CGLIB代理
    • Spring AOP的注解方式
      • @Aspect注解
      • @EnableAspectJAutoProxy注解
    • Spring AOP的工作流程
    • 拓展應用
      • 1. 自定義注解
      • 2. 異常處理
      • 3. 切面優先級
    • 結論

在這里插入圖片描述

🎉深入理解Spring AOP的工作流程


  • ☆* o(≧▽≦)o *☆嗨~我是IT·陳寒🍹
  • ?博客主頁:IT·陳寒的博客
  • 🎈該系列文章專欄:架構設計
  • 📜其他專欄:Java學習路線 Java面試技巧 Java實戰項目 AIGC人工智能 數據結構學習
  • 🍹文章作者技術和水平有限,如果文中出現錯誤,希望大家能指正🙏
  • 📜 歡迎大家關注! ??

引言

在現代的軟件開發中,面向切面編程(AOP)是一種重要的編程范式,用于解耦業務邏輯和橫切關注點(cross-cutting concerns)。Spring框架提供了強大而靈活的AOP支持,通過代理機制實現橫切關注點的注入。本文將深入探討Spring AOP的工作流程,幫助讀者更好地理解其原理和應用。

什么是AOP?

AOP是一種編程思想,通過在程序中間插入橫切關注點,將系統劃分為核心業務邏輯和橫切關注點兩部分。橫切關注點包括日志記錄、事務管理、安全控制等與核心業務邏輯無關但又必須在程序中執行的功能。AOP通過將這些橫切關注點與核心業務邏輯分離,提高了代碼的模塊化和可維護性。

Spring AOP通過代理機制實現橫切關注點的注入,其中代理對象負責執行橫切邏輯。在Spring AOP中,常見的橫切關注點包括日志記錄、性能監控、事務管理等。

Spring AOP的工作原理

Spring AOP基于代理模式,主要通過兩種方式實現:

  1. JDK動態代理: 基于接口的代理機制,使用java.lang.reflect.Proxy類生成代理對象。

  2. CGLIB代理: 基于類的代理機制,使用CGLIB庫生成代理對象。

1. JDK動態代理

JDK動態代理要求目標類實現一個或多個接口,代理對象實現這些接口并委托給目標對象。以下是一個簡單的例子:

public interface UserService {void addUser(String username, String password);
}public class UserServiceImpl implements UserService {@Overridepublic void addUser(String username, String password) {// 實際業務邏輯System.out.println("User added: " + username);}
}public class LogAspect implements InvocationHandler {private Object target;public LogAspect(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Log: Method " + method.getName() + " is invoked");Object result = method.invoke(target, args);return result;}
}// 使用代理
public class Main {public static void main(String[] args) {UserService target = new UserServiceImpl();InvocationHandler handler = new LogAspect(target);UserService proxy = (UserService) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler);proxy.addUser("John", "123456");}
}

2. CGLIB代理

CGLIB代理不要求目標類實現接口,代理對象繼承目標對象。以下是一個簡單的例子:

public class UserService {public void addUser(String username, String password) {// 實際業務邏輯System.out.println("User added: " + username);}
}public class LogAspect implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("Log: Method " + method.getName() + " is invoked");Object result = proxy.invokeSuper(obj, args);return result;}
}// 使用代理
public class Main {public static void main(String[] args) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(UserService.class);enhancer.setCallback(new LogAspect());UserService proxy = (UserService) enhancer.create();proxy.addUser("John", "123456");}
}

Spring AOP的注解方式

除了基于XML的配置方式,Spring AOP還支持使用注解的方式配置切面。

@Aspect注解

在使用注解方式配置AOP時,首先需要使用@Aspect注解聲明一個切面類。該類包含了多個切點和通知,用于定義橫切邏輯。

@Aspect
@Component
public class LogAspect {@Pointcut("execution(* com.example.service.*.*(..))")public void pointcut() {}@Before("pointcut()")public void beforeAdvice(JoinPoint joinPoint) {System.out.println("Log: Before " + joinPoint.getSignature().getName());}@After("pointcut()")public void afterAdvice(JoinPoint joinPoint) {System.out.println("Log: After " + joinPoint.getSignature().getName());}
}

上述例子中,@Pointcut注解定義了一個切點,表示匹配com.example.service包下所有類的所有方法。@Before@After注解分別表示前置通知和后置通知。

@EnableAspectJAutoProxy注解

在Spring Boot中,還需要在配置類上使用@EnableAspectJAutoProxy注解開啟自動代理功能。該注解告訴Spring Boot啟用AspectJ自動代理。

@SpringBootApplication
@EnableAspectJAutoProxy
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

Spring AOP的工作流程

Spring AOP的工作流程可以概括為以下幾個步驟:

  1. 定義切面: 創建一個Java類,并在類上使用@Aspect注解聲明為切面類。在切面類中定義切點和通知。

  2. 配置通知: 使用@Before@After等注解配置通知,定義橫切邏輯。

  3. 激活切面: 在配置類上使用@EnableAspectJAutoProxy注解激活切面。

  4. 容器初始化: Spring容器啟動時,會掃描并解析所有標有@Aspect注解的類。

  5. 生成代理對象: 對于被代理的目標對象,Spring會根據切面定義生成代理對象。代理對象包含了橫切邏輯。

  6. 執行橫切邏輯: 在目標方法執行前、后或異常時,執行橫切邏輯。

拓展應用

Spring AOP的應用遠不止上述簡單例子所示,還可以結合更復雜的切面和通知,實現更豐富的橫切邏輯。以下是一些拓展應用的示例:

1. 自定義注解

可以使用自定義注解來標記切點,讓代碼更具可讀性。例如,定義一個@Log注解,標記需要記錄日志的方法。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {String value() default "";
}

然后,在切面類中使用@Around注解攔截被@Log注解標記的方法。

@Aspect
@Component
public class LogAspect {@Around("@annotation(com.example.annotation.Log)")public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("Log: Method " + joinPoint.getSignature().getName() + " is invoked");Object result = joinPoint.proceed();return result;}
}

2. 異常處理

通過@AfterThrowing注解可以實現異常處理邏輯,記錄異常信息或進行其他處理。

@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex")
public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex) {System.out.println("Exception: " + ex.getMessage());
}

3. 切面優先級

通過@Order注解可以指定切面的優先級,數字越小,優先級越高。

@Aspect
@Component
@Order(1)
public class LogAspect {// ...
}

在這里插入圖片描述

結論

Spring AOP是Spring框架中一個重要的組件,通過代理機制實現橫切關注點的注入。本文深入介紹了Spring AOP的工作原理,包括基于JDK動態代理和CGLIB代理的實現方式,以及使用注解配置AOP的方法。通過理解Spring AOP的工作流程,我們能更好地應用和拓展AOP,提高代碼的模塊化和可維護性。希望本文能夠幫助讀者更深入地理解和應用Spring AOP。


🧸結尾 ?? 感謝您的支持和鼓勵! 😊🙏
📜您可能感興趣的內容:

  • 【Java面試技巧】Java面試八股文 - 掌握面試必備知識(目錄篇)
  • 【Java學習路線】2023年完整版Java學習路線圖
  • 【AIGC人工智能】Chat GPT是什么,初學者怎么使用Chat GPT,需要注意些什么
  • 【Java實戰項目】SpringBoot+SSM實戰:打造高效便捷的企業級Java外賣訂購系統
  • 【數據結構學習】從零起步:學習數據結構的完整路徑

在這里插入圖片描述

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

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

相關文章

關于運行軟件程序出現vcruntime140.dll丟失的修復教程-解決方案

vcruntime140.dll是Microsoft Visual C庫文件的一部分,用于支持Windows操作系統上的應用程序。如果找不到或丟失了這個文件,可能會導致某些應用程序無法正常運行。下面是關于vcruntime140.dll丟失的5個修復方法,以及vcruntime140.dll文件屬性…

Python基礎教程之分支結構詳解

文章目錄 一、分支結構二、單分支結構三、雙分支結構四、多分支結構五、嵌套分支結構六、三元表達式七、條件測試關于Python技術儲備一、Python所有方向的學習路線二、Python基礎學習視頻三、精品Python學習書籍四、Python工具包項目源碼合集①Python工具包②Python實戰案例③P…

Elasticsearch基礎優化

分片策略 分片和副本得設計為ES提供支付分布式和故障轉移得特性,但不意味著分片和副本是可以無限分配, 而且索引得分片完成分配后由于索引得路由機制,不能重新修改分片數(副本數可以動態修改) 一個分片得底層為一個l…

python之pyqt專欄2-項目文件解析

項目結構 在上一篇文章python之pyqt專欄1-環境搭建,創建新的pyqt項目,下面我們來看一下這個項目下的文件。 從下面的文件結構圖可以看到,該項目下有3個文件,untitled.ui,untitled.py 以及main.py。 QtDesigner可以UI界面的方式&am…

Feign接口請求返回異常 no suitable HttpMessageConvert found for response type

問題場景&#xff1a; 后端調用feign接口請求, 接口返回異常, no suitable HttpMessageConvert found for response type 問題描述 報錯異常如下&#xff1a; //根據圖片特征 去查詢人員信息ResultVo<List> personVos ipbdFaceLibPersonApi.queryFacePersonByFeatur…

華為云之SFS彈性文件服務使用體驗

華為云之SFS彈性文件服務使用體驗 一、本次實踐介紹1.1 實踐環境簡介1.2 本次實踐目的 二、SFS彈性文件服務介紹2.1 SFS彈性文件服務簡介2.2 SFS彈性文件服務特點 三、購買ECS彈性云服務器3.1 購買ECS彈性云服務器3.2 查看ECS彈性云服務器狀態3.3 遠程連接ECS3.4 檢查操作系統版…

package.json 中的版本號,符號 ~ 與 ^ 的區別及其他符號的含義

"element-ui": "^2.15.1", 版本號&#xff1a; 2.15.1 對應 x.y.z z &#xff1a;表示一些小的bugfix, 更改z的號&#xff1b;(修復補丁-z)&#xff08;~符號&#xff09; y &#xff1a;表示一些大的版本更改&#xff0c;比如一些API的變化&#xff1b;(…

迭代器模式 (Iterator Pattern)

定義 迭代器模式&#xff08;Iterator Pattern&#xff09;是一種行為型設計模式&#xff0c;用于順序訪問集合對象的元素&#xff0c;而無需知道集合對象的底層表示。迭代器模式將遍歷集合的責任從集合對象轉移到迭代器對象上&#xff0c;這簡化了集合接口和實現&#xff0c;…

計算機應用基礎_錯題集_基礎知識---網絡教育統考工作筆記006

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 前言一、基礎知識部分錯題集總結前言 計算機應用基礎統考,錯題集總結 一、基礎知識部分 基礎知識部分 2、微處理器芯片的位數即指______。 A.速度 B.字長 C.

Unity Android FireBase bugly報錯查詢

報錯如下圖&#xff0c;注意&#xff0c;標紅的三處 使用的il2cpp和架構是arm64-v8a 那我們就可以根據這些去找對應的符號表&#xff0c;在unity安裝目錄下 Unity2020.3.33f1\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Symbols\arm64-v8a 找到l…

Tomcat注冊為服務后,如何配置Tomcat內存大小

前提條件&#xff1a;tomcat已經注冊為服務。 1.winR,輸入regedit打開注冊表 2.找到Tomcat注冊表路徑&#xff1a; HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Apache Software Foundation\Procrun 2.0\Tomcat80603.找到jvm內存配置路徑&#xff1a; HKEY_LOCAL_MACHINE\SOFTW…

PTA-6-312 使用多態實現圖書館計算罰金功能

題目&#xff1a; 圖書館提供給讀者借閱服務&#xff0c;包括借閱書籍及音像制品。如果借閱超時需要繳納罰金。對于不同類型的書籍和音像制品罰款規則不同。 成人書籍:允許借閱的時間是21天&#xff0c;每超時1天&#xff0c;需要繳納罰金2元;如果超時3天以上&#xff0c;超出的…

vue中 mixin用法

在Vue.js中&#xff0c;mixin是一種可以在多個組件之間共享Vue組件選項的靈活方式。mixin對象可以包含任何組件選項。當組件使用mixin時&#xff0c;所有mixin對象的選項將被“混合”到該組件的選項中。 使用mixin的一個主要優點是可以在多個組件之間重用和共享代碼。這可以幫…

SSM大學生社團信息管理系統-99953,(免費領取源碼)計算機畢業設計選題開題+程序定制+論文書寫+答辯ppt書寫 包售后 全流程

SSM大學生社團信息管理系統APP 摘 要 隨著科學技術的飛速發展&#xff0c;社會的方方面面、各行各業都在努力與現代的先進技術接軌&#xff0c;通過科技手段來提高自身的優勢&#xff0c;高校當然也不能排除在外。大學生社團信息管理系統APP是以實際運用為開發背景&#xff0c…

CMake中常見的預定義變量

文章目錄 CMake常見的預定義變量CMake variables官方文檔 CMake常見的預定義變量 在 CMake 中&#xff0c;有一些常見的預定義變量&#xff0c;它們提供了有關項目、目錄結構和構建環境的信息。這些變量可用于設置路徑、傳遞參數、以及進行其他與構建過程相關的操作。 以下是…

Rust語言入門教程(五) - 流控制語句

if 表達式 在Rust中&#xff0c; if語句的判斷條件不需要用( )括起來&#xff0c; 它會認為所有在if 和 {之間的表達式就是判斷條件&#xff0c;例如&#xff1a; if num 5 {msg "five"; }判斷條件的表達式必須返回一個bool型的值&#xff0c; 因為Rust是一個不喜…

[C/C++]數據結構 循環隊列

前言: 隊列是一種具有先進先出特性的結構,但是當數據出隊列以后,前面的空間就無法再次利用了,循環隊列就可以解決這個問題 一:概念及結構: 1.循環隊列概念 循環隊列是一種線性數據結構&#xff0c;其操作表現基于 FIFO&#xff08;先進先出&#xff09;原則并且隊尾被連接在隊…

顛覆與創新:算法備案的雙重挑戰

隨著數字時代的迅猛發展&#xff0c;算法已經成為了企業創新和競爭的關鍵因素。然而&#xff0c;伴隨著算法的廣泛應用&#xff0c;數據隱私、法規合規等問題也愈發凸顯&#xff0c;給企業帶來了雙重挑戰。本文將深入探討這一話題&#xff0c;探討算法備案如何在顛覆與創新之間…

IDEA、PHPSTORM 在命令行中進行 PHP debug

然在終端執行控制器的方法php yii test/ab 即可看到觸發debug 調試

視頻剪輯技巧:多個視頻合并新篇章,高效視頻剪輯,創造無限可能

在數字媒體時代&#xff0c;視頻剪輯已經成為一項重要的技能。多個視頻合并是一種將多個視頻片段合并成一個完整視頻的技巧。這種技巧可以將不同的視頻片段組合在一起&#xff0c;制作出獨特且具有吸引力的視頻內容。現在一起操作下云炫AI智剪如何批量合并視頻的操作吧。 一、準…