Spring AOP的兩種代理方式
阿新 • • 發佈:2019-01-28
Spring AOP是通過為目標物件建立代理來實現的。其使用的代理方式有兩種:
- JDK 動態代理 (目標物件實現了介面時使用,只會代理目標介面方法)
- CGLIB (當目標物件沒有實現介面時只能使用CGLIB ,當然可以通過配置強制有介面的物件也使用CGLIB)
CGLIB是通過為目標物件生成的子類來實現代理,因此對於final修飾的方法沒有作用。另外目標物件的構造方法將被呼叫兩次。
CGLIB和JDK動態代理的優缺點:
- CGLIB執行代理的效能高,但是建立時耗費的時間長(通過操作目標物件的位元組碼建立);
配置proxy-target-class
通過配置可以強制Spring AOP只使用CGLIB :設定proxy-target-class=true;
<aop:config proxy-target-class="true">
<!-- other beans defined here... -->
</aop:config>
<!--該引數也可在下面標籤上使用 -->
<tx:annotation-driven/>
<aop:aspectj-autoproxy/>
注意
當一個bean定義為pointcut後, 若該bean使用了JDK動態代理,則getBean時必須使用其介面形式,且介面不能強轉為其實現類,否則為報錯。
程式碼如下:
// IPerson為介面, PersonService是其實現類 ,PersonService配置為pointcut
// getBean強轉為實現類時執行報錯 $Prox4 cannot be cast to PersonService
//IPerson person = (PersonService) context.getBean("person");
IPerson person = (IPerson) context.getBean("person");
// 當對person執行強轉時同樣報錯
PersonService service = (PersonService) person;
當使用CGLIB代理方式時不會有上述錯誤。