Spring AOP失效的常見場景分析
前言
Spring的AOP(面向切面編程)是一種強大的技術(shù),用于在應(yīng)用程序中實現(xiàn)橫切關(guān)注點的模塊化。雖然Spring的AOP在大多數(shù)情況下都是有效的,但在某些場景下可能會失效。下面來分析Spring AOP失效的常見場景
首先,Spring的AOP其實是通過動態(tài)代理實現(xiàn)的,所以,想要讓AOP生效,前提必須是動態(tài)代理生效,并且可以調(diào)用到代理對象的方法
1.非Spring管理的對象
Spring的AOP只能攔截由Spring容器管理的Bean對象。如果您使用了非受Spring管理的對象,則AOP將無法對其進行攔截。
2.同一個Bean內(nèi)部方法調(diào)用
如果一個Bean內(nèi)部的方法直接調(diào)用同一個Bean內(nèi)部的另一個方法,AOP將無法攔截這個內(nèi)部方法調(diào)用。因為AOP是基于代理的,只有通過代理對象才能觸發(fā)AOP攔截。
@Component public class MyBean { public void method1() { System.out.println("Inside method1"); method2(); // 直接調(diào)用同一個 Bean 內(nèi)部的另一個方法 } public void method2() { System.out.println("Inside method2"); } }
假設(shè)我們有一個名為 MyBean
的類,其中包含了兩個方法 method1()
和 method2()
。在 method1()
中,直接調(diào)用了 method2()
方法。
現(xiàn)在,讓我們創(chuàng)建一個切面來攔截 method1()
的執(zhí)行,并打印一些日志信息:
@Aspect @Component public class MyAspect { @Before("execution(* com.example.MyBean.method1())") public void beforeMethod1() { System.out.println("Before method1 execution"); } }
上述切面使用 @Before
注解來定義了一個前置通知,在執(zhí)行 MyBean
類的 method1()
方法之前被觸發(fā)。
然后,我們在 Spring 應(yīng)用程序中使用這兩個組件:
@SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); MyBean myBean = ApplicationContext.getBean(MyBean.class); myBean.method1(); } }
當(dāng)我們運行應(yīng)用程序時,我們會發(fā)現(xiàn) "Before method1 execution" 這條日志信息被打印出來,但是 "Inside method2" 這條日志信息卻沒有被打印出來。這是因為 AOP 無法攔截 method2()
的直接調(diào)用,而只能攔截通過代理對象觸發(fā)的方法調(diào)用。
3.靜態(tài)方法
Spring的AOP只能攔截非靜態(tài)方法。如果您嘗試攔截靜態(tài)方法,AOP將無法生效。
4.final方法
AOP無法攔截final方法。final方法是不可重寫的,因此AOP無法生成代理對象來攔截這些方法。
直接在對象內(nèi)部調(diào)用方法:如果您直接在對象內(nèi)部調(diào)用方法而不通過代理對象,AOP將無法攔截。因此,建議始終通過代理對象調(diào)用方法以確保AOP的生效。
5.異步方法
對于使用Spring的異步特性(如@Async注解)的方法,AOP攔截器可能無法正常工作。這是因為異步方法在運行時會創(chuàng)建新的線程或使用線程池,AOP攔截器無法跟蹤到這些新線程中的方法調(diào)用。
總結(jié)
以下幾種情況會導(dǎo)致AOP失效:
非Spring管理的對象
私有方法調(diào)用
靜態(tài)方法調(diào)用
final方法調(diào)用
類內(nèi)部自調(diào)用
內(nèi)部類方法調(diào)用
異步方法
以上就是Spring AOP失效的常見場景分析的詳細內(nèi)容,更多關(guān)于Spring AOP失效場景的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot中@RestControllerAdvice注解實現(xiàn)全局異常處理類
這篇文章主要介紹了SpringBoot中@RestControllerAdvice注解全局異常處理類,springboot中使用@RestControllerAdvice注解,完成優(yōu)雅的全局異常處理類,可以針對所有異常類型先進行通用處理后再對特定異常類型進行不同的處理操作,需要的朋友可以參考下2024-01-01springboot?bootstrap.yml?nacos配置中心問題
這篇文章主要介紹了springboot?bootstrap.yml?nacos配置中心問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03Nacos啟動出現(xiàn)failed to req API:/nacos/v1/ns/insta
這篇文章主要介紹了Nacos啟動出現(xiàn)failed to req API:/nacos/v1/ns/instance after all servers問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08使用Spring Boot快速構(gòu)建基于SQLite數(shù)據(jù)源的應(yīng)用
為了提供一個單包易部署的服務(wù)器應(yīng)用,考慮使用Spring Boot,因為其集成了Apache Tomcat,易于運行,免去絕大部分了服務(wù)器配置的步驟2017-08-08SpringBoot?MP簡單的分頁查詢測試實現(xiàn)步驟分解
好久沒水后端的東西了,最近在做vue項目寫前端的代碼,所以cloud也停進度了,吃完飯突然記得我沒有在博客里寫分頁的東西,雖然項目中用到了,但是沒有拎出來,這里就拎出來看看2023-04-04SpringBoot如何配置MySQL和Oracl雙數(shù)據(jù)源(Mybatis)
這篇文章主要介紹了SpringBoot如何配置MySQL和Oracl雙數(shù)據(jù)源(Mybatis)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03