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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

aop阻止方法运行_Spring AOP无法拦截内部方法调用

發布時間:2024/9/27 javascript 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 aop阻止方法运行_Spring AOP无法拦截内部方法调用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

假設一個接口里面有兩個方法:

package demo.long;public interfaceCustomerService {public voiddoSomething1();public voiddoSomething2();

}

接口實現類如下:

package demo.long.impl;import demo.long.CustomerService;public class CustomerServiceImpl implementsCustomerService {public voiddoSomething1() {

System.out.println("CustomerServiceImpl.doSomething1()");

doSomething2();

}public voiddoSomething2() {

System.out.println("CustomerServiceImpl.doSomething2()");

}

}

現在我需要在CustomerService接口的每個方法被調用時都在方法前執行一些邏輯,所以需要配置一個攔截器:

package demo.long;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Before;

@Aspectpublic classCustomerServiceInterceptor {

@Before("execution(* demo.long..*.*(..))")public voiddoBefore() {

System.out.println("do some important things before...");

}

}

把Bean加到Spring配置中

如果現在外部對象調用CustomerService的doSomething1()方法的時候,會發現只有doSomething1()方法執行前打印了“do some important things before...”,而doSomething1()內部調用doSomething2()時并沒有打印上述內容;外部對象單獨調用doSomething2()時會打印上述內容。

public classCustomerServiceTest {

@Autowired

ICustomerService customerService;

@Testpublic voidtestAOP() {

customerService.doSomething1();

}

}

原因分析

攔截器的實現原理就是動態代理,實現AOP機制。Spring 的代理實現有兩種:一是基于 JDK Dynamic Proxy 技術而實現的;二是基于 CGLIB 技術而實現的。如果目標對象實現了接口,在默認情況下Spring會采用JDK的動態代理實現AOP,CustomerServerImpl正是這種情況。

JDK動態代理生成的CustomerServiceImpl的代理類大致如下:

public class CustomerServiceProxy implementsCustomerService {privateCustomerService customerService;public voidsetCustomerService(CustomerService customerService) {this.customerService =customerService;

}public voiddoSomething1() {

doBefore();

customerService.doSomething1();

}public voiddoSomething2() {

doBefore();

customerService.doSomething2();

}private voiddoBefore() {//例如,可以在此處開啟事務或記錄日志

System.out.println("do some important things before...");

}

}

客戶端程序使用代理類對象去調用業務邏輯:

public classTestProxy {public static voidmain(String[] args) {//創建代理目標對象//對于Spring來說,這一工作是由Spring容器完成的。

CustomerService serviceProxyTarget = newCustomerServiceImpl();//創建代理對象//對于Spring來說,這一工作也是由Spring容器完成的。

CustomerServiceProxy serviceProxy = newCustomerServiceProxy();

serviceProxy.setCustomerService(serviceProxyTarget);

CustomerService serviceBean=(CustomerService) serviceProxy;//調用業務邏輯操作

serviceBean.doSomething1();

}

}

執行main方法,發現doSomething1()中調用doSomething2()方法的時候并未去執行CustomerServiceProxy類的doBefore()方法。其實doSomething2()等同于this.doSomething2(),在CustomerServiceImpl類中this關鍵字表示的是當前這個CustomerServiceImpl類的實例,所以程序會去執行CustomerServiceImpl對象中的doSomething2()方法,而不會去執行CustomerServiceProxy類對象中的 doSomething2()方法。

在使用Spring AOP的時候,我們從IOC容器中獲取的Bean對象其實都是代理對象,而不是那些Bean對象本身,由于this關鍵字引用的并不是該Service Bean對象的代理對象,而是其本身,因此Spring AOP是不能攔截到這些被嵌套調用的方法的。

解決方案

修改類,不要出現“自調用”的情況:這是Spring文檔中推薦的“最佳”方案;

若一定要使用“自調用”,那么this.doSomething2()替換為:((CustomerService) AopContext.currentProxy()).doSomething2();此時需要修改spring的aop配置:

總結

以上是生活随笔為你收集整理的aop阻止方法运行_Spring AOP无法拦截内部方法调用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。