1. 程式人生 > >Spring AOP的兩種代理方式

Spring AOP的兩種代理方式

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代理方式時不會有上述錯誤。