Spring?this調(diào)用當(dāng)前類方法無法攔截的示例代碼
先給出代碼示例
package com.example.demo.service; import org.springframework.stereotype.Service; @Service public class ProxyService { public void testA(){ System.out.println("進入A"); this.testB(); } public void testB() { System.out.println("進入b"); } }
package com.example.demo.annotation; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect @Component public class AspectjTest { @Around("execution(* com.example.demo.service.ProxyService.testB())") public void recordProxy(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); joinPoint.proceed(); long end = System.currentTimeMillis(); System.out.println("花費時間:"+(end-start)); } }
package com.example.demo.api; import com.example.demo.service.ProxyService; import com.example.demo.service.UserService; import org.springframework.aop.framework.AopContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; @Controller public class ProxyApi { // @Autowired // ProxyService proxyService1; @Autowired private ApplicationContext applicationContext; @PostMapping("/proxy") public String test1() { ProxyService proxyService1 = applicationContext.getBean(ProxyService.class);; proxyService1.testA(); return "string"; } }
運行上面的代碼會發(fā)現(xiàn) 配置aop 攔截方法不會被執(zhí)行
我們通過debug 查看這個proxyService1 和this的區(qū)別,看看他們的值是什么
發(fā)現(xiàn)不一樣,其實這就是問題的原因。
1、當(dāng)我們在aop配置攔截的時候會指定類下面的方法路徑,在spring啟動的時候會先去加載這個ProxyService類,生成一個bean,但是因為你用aop配置了,所以需要代理這個ProxyService類,所以最終存在spring容器中的bean對象就是被代理后的bean對象。所以,我們在用容器獲取bean或者用依賴注入獲取bean的地址路徑顯示的是被代理后的bean 。
2、this獲取的當(dāng)前對象方法的一個引用,所以在調(diào)用testB方法的時候用的不是被代理的對象,自熱不會經(jīng)過aop攔截,原理和我們使用普通動態(tài)代理一樣,只能是代理對象才能走自定義的方法。
3、可以通過debug 查看當(dāng)ProxyService類被代理前和后的zhi值
發(fā)現(xiàn)是和之前的debug截圖里面的值相符合的哈。
解決方法,就是在調(diào)用testB方法的時候用spring容器里的bean對象
@Service public class ProxyService { @Autowired private ProxyService proxyService; public void testA(){ System.out.println("進入A"); proxyService.testB(); } public void testB() { System.out.println("進入b"); }
或者
@Service public class ProxyService { public void testA(){ System.out.println("進入A"); ProxyService currentProxy = (ProxyService) AopContext.currentProxy(); currentProxy.testB(); } public void testB() { System.out.println("進入b"); } }
最終結(jié)果正確
到此這篇關(guān)于Spring this調(diào)用當(dāng)前類方法無法攔截的文章就介紹到這了,更多相關(guān)Spring this無法攔截內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決springSecurity 使用默認登陸界面登錄后無法跳轉(zhuǎn)問題
這篇文章主要介紹了解決springSecurity 使用默認登陸界面登錄后無法跳轉(zhuǎn)問題,項目環(huán)境springboot下使用springSecurity 版本2.7.8,本文通過實例代碼給大家介紹的非常詳細,需要的朋友參考下吧2023-12-12SpringBoot使用@Async注解實現(xiàn)異步調(diào)用
這篇文章主要介紹了SpringBoot使用@Async注解實現(xiàn)異步調(diào)用,異步調(diào)用是相對于同步調(diào)用而言的,同步調(diào)用是指程序按預(yù)定順序一步步執(zhí)行,每一步必須等到上一步執(zhí)行完后才能執(zhí)行,異步調(diào)用則無需等待,程序執(zhí)行完即可執(zhí)行,可以減少程序執(zhí)行時間,需要的朋友可以參考下2023-10-10Java中使用StackWalker和Stream API進行堆棧遍歷
StackWalking API是添加到Java中最酷的(并且對大多數(shù)開發(fā)人員來說完全不切實際,一般不會用,除非深層跟蹤調(diào)優(yōu))的功能之一。在這篇簡短的文章中,我們將看到它是什么以及使用它有多么容易,很快的認識它2018-09-09詳解Springboot整合Dubbo之代碼集成和發(fā)布
本篇文章主要介紹了Springboot整合Dubbo之代碼集成和發(fā)布,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12springboot基于keytool實現(xiàn)https的雙向認證示例教程
這篇文章主要介紹了springboot基于keytool實現(xiàn)https的雙向認證,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-06-06