日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

[Done]Spring @Pointcut 切点调用不到(SpringAOP嵌套方法不起作用) 注意事项

發(fā)布時間:2024/8/26 javascript 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Done]Spring @Pointcut 切点调用不到(SpringAOP嵌套方法不起作用) 注意事项 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

今天在開發(fā)過程中,遇到一個問題卡了很久,測試代碼如下:

package spring.pointcut;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut;/*** @Description: Pointcut測試* @Author: qionghui.fang* @Date: 2018/10/23 上午10:10*/ @Aspect public class TargetMonitor {// 配置方法1 // @Pointcut("execution(* spring.pointcut.Target.onEvent(String))") // private void anyMethod() {} // @Around("anyMethod()")//配置方法2@Around("execution(* spring.pointcut.Target.onEvent(..))")public Object monitor(ProceedingJoinPoint point) throws Throwable {System.out.println("before");try {return point.proceed();} finally {System.out.println("after");}} }

目標(biāo)類:

public class Target {public void otherEvent(){System.out.println("Call otherEvent()");}public boolean onEvent(Integer type, Long Value){System.out.println("Call onEvent(Integer type, Long Value)");for (int i=0; i<=3; i++){onEvent("");}System.out.println("End Call onEvent(Integer type, Long Value)");return true;}public boolean onEvent(String type){System.out.println("Call onEvent(String type)");return true;}}

Main方法:

public class Main {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/spring.xml");Target target = (Target) ctx.getBean("target");System.out.println("\n*****************************");target.onEvent(1,1L);System.out.println("\n*****************************");target.onEvent("");System.out.println("\n*****************************");target.otherEvent();System.out.println("\n*****************************");} }

spring.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><bean id="target" class="spring.pointcut.Target"/><bean id="monitor" class="spring.pointcut.TargetMonitor"/><!-- 基于@AspectJ切面的驅(qū)動器 --><aop:aspectj-autoproxy proxy-target-class="true"/></beans>

結(jié)果輸出:

22:14:25.092 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'target'***************************** 22:14:25.096 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'monitor' before Call onEvent(Integer type, Long Value) Call onEvent(String type) Call onEvent(String type) Call onEvent(String type) Call onEvent(String type) End Call onEvent(Integer type, Long Value) after***************************** before Call onEvent(String type) after***************************** Call otherEvent()*****************************

問題描述:

在目標(biāo)類里有兩個同名的onEvent方法,下面這個是目標(biāo)切點方法,但是系統(tǒng)調(diào)用時,方法入口是上面的onEvent方法,所以怎么都執(zhí)行不到想要的邏輯。

其實想一想動態(tài)代理,是代理的類這一層級,關(guān)于類中方法的相互調(diào)用,是不能侵入這么深的。

注意:切點方法當(dāng)前僅當(dāng)在類執(zhí)行入口時才能被調(diào)用,而非類內(nèi)部的其他接口調(diào)用。

?

原理跟蹤,跟蹤生成的動態(tài)代理類:

import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; import spring.dynamicproxy.IFace;public final class Target1$Proxy extends Proxy implements Target {private static Method m1;private static Method m2;private static Method m3;private static Method m4;private static Method m5;private static Method m0;static {try {m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));m2 = Class.forName("java.lang.Object").getMethod("toString");m3 = Class.forName("spring.dynamicproxy.Target").getMethod("onEvent");m4 = Class.forName("spring.dynamicproxy.Target").getMethod("onEvent1");m5 = Class.forName("spring.dynamicproxy.Target").getMethod("otherEvent");m0 = Class.forName("java.lang.Object").getMethod("hashCode");} catch (NoSuchMethodException var2) {throw new NoSuchMethodError(var2.getMessage());} catch (ClassNotFoundException var3) {throw new NoClassDefFoundError(var3.getMessage());}}public Target1$Proxy(InvocationHandler var1) throws {super(var1);}public final boolean onEvent() throws {try {return (Boolean)super.h.invoke(this, m3, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final boolean onEvent1() throws {try {return (Boolean)super.h.invoke(this, m4, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final void otherEvent() throws {try {super.h.invoke(this, m5, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}}

?

上述省略了部分其他方法,大家關(guān)注這個動態(tài)代理類內(nèi)容,

JDK的動態(tài)代理核心是生成了一個新的代理類,這個代理類基礎(chǔ)Proxy類,實現(xiàn)了目標(biāo)對象的接口,而在具體方法執(zhí)行時,

調(diào)用super.h.invoke,這里的super.h 是指我們初始化動態(tài)代理的InvocationHandler,這里有點繞,大家要好好理解。

也就是說動態(tài)代理生效的方法是,當(dāng)調(diào)用代理類Target.m的目標(biāo)方法時,其實執(zhí)行的是ProxyTarget.m,

這樣我們在切點中round前后的邏輯就可以執(zhí)行到。

但是當(dāng)執(zhí)行round中的super.h.invoke時,這個方法里執(zhí)行的是原始類的原生邏輯,比如執(zhí)行上述例子的onEvent1,

但onEnvent1中調(diào)用onEvent時,是執(zhí)行的this.onEvent,而非ProxyTarget.onEvent,

這便是為什么上述例子無法執(zhí)行的底層核心原因。

?

這篇文章也描述了類似的問題:https://blog.csdn.net/bobozai86/article/details/78896487

?

解決辦法:

1、在調(diào)用點使用代理類,而非this調(diào)用:

main中獲取容器對象的測試方法:

?

?

2、思考業(yè)務(wù)層面,是否可以切在更內(nèi)層的方法。

?

本質(zhì)還是要理解動態(tài)代理的實現(xiàn)原理。

?

以上。

?

轉(zhuǎn)載于:https://www.cnblogs.com/do-your-best/p/9839846.html

總結(jié)

以上是生活随笔為你收集整理的[Done]Spring @Pointcut 切点调用不到(SpringAOP嵌套方法不起作用) 注意事项的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 一级片在线播放 | 成人手机在线视频 | 成人av影院在线观看 | 综合久久久久久久 | 黄色a级免费 | 欧美日一区二区三区 | 亚洲国产毛片 | 成人综合婷婷国产精品久久 | 欧美三级韩国三级日本三斤在线观看 | 日韩精品免费一区二区 | 精品一区二区电影 | 一级片视频免费 | 日本人性爱视频 | 91二区| 成人看片免费 | 成人深夜福利视频 | 一本久道视频一本久道 | av一区二区三区免费观看 | 五月婷婷开心 | 国产在线视频第一页 | 日韩av在线第一页 | 亚洲少妇一区 | 小sao货水好多真紧h无码视频 | 99热精品在线播放 | 国产理论视频 | 久久爱网| 日本a∨视频 | 欧美激情精品久久久久久蜜臀 | 亚洲欧洲一区二区 | 欧美 日本 国产 | 亚洲天堂精品在线观看 | xvideos永久免费入口 | 色综合亚洲 | 成人免费网站在线 | 精品国产成人 | 9191久久 | 天天色综合久久 | 午夜视频免费在线观看 | 毛片一级视频 | 人人澡人人爽 | 日韩av一| jizzzz中国 | 欧美第四页 | 99er在线观看| 欧美日韩综合视频 | 毛片a | 色老头一区二区三区在线观看 | 大j8黑人w巨大888a片 | 91高潮大合集爽到抽搐 | 手机av免费观看 | 大肉大捧一进一出好爽 | 久久久久xxxx| 欧美成人一二三区 | 欧美日本中文字幕 | 妞干网精品 | 国产成人精品亚洲精品色欲 | 久久久99精品国产一区二区三区 | 国产日韩一区二区 | 男操女视频网站 | 黄网址在线观看 | 男人天堂手机在线 | 欧美又大又硬又粗bbbbb | 男女做激情爱呻吟口述全过程 | 精品自拍一区 | 玉势 (1v1 高h) | 四虎在线播放 | 亚洲porn| 色屁屁一区二区三区视频 | 色噜噜狠狠狠综合曰曰曰 | 久草免费资源站 | 欧美午夜精品久久久久久浪潮 | 久久精品亚洲天堂 | 无码无遮挡又大又爽又黄的视频 | 欧美性猛片aaaaaaa做受 | caobi视频 | 女人18岁毛片 | 亚洲成人一区 | 嫩草影院国产 | 土耳其xxxx性hd极品 | 国产又粗又长又黄的视频 | 男男一级淫片免费播放 | 求av网址 | 日韩免费在线观看 | 欧美人妻精品一区二区免费看 | 亚洲av片不卡无码久久 | 成年人毛片视频 | 尤物视频在线播放 | 最新成人| 最新日韩在线 | 日本视频中文字幕 | 牛牛免费视频 | 日本十大三级艳星 | 成人免费视频网 | 亚洲精品国产视频 | 少妇学院在线观看 | 国产传媒一区二区三区 | 黄色国产一级 | 亚洲区一区二区 | 色999在线 |