1. 程式人生 > >轉:Spring AOP中的動態代理

轉:Spring AOP中的動態代理

原文連結:Spring AOP中的動態代理

  • 0  前言
  • 1  動態代理
    • 1.1 JDK動態代理
    • 1.2 CGLIB動態代理
      • 1.2.1 CGLIB的代理用法
      • 1.2.2 CGLIB的過濾功能
  • 2  Spring AOP中的動態代理機制
    • 2.1 JdkDynamicAopProxy
    • 2.2 CglibAopProxy
  • 3 總結

0  前言

    前一個季度旅遊TDC的Thames服務有幾次宕機,根據組內原因認真查詢發現是資料庫事務造成的,後來把服務中的事務配置全部去掉,服務恢復正常。根據這次教訓,雖然現在還是很難確定是哪一個方面的真正原因,但是激發了我學習Spring事務方面的興趣。而Spring事務的實現是根據AOP來實現的,對於我這個小菜鳥,只能一步一步來了,決定先從Spring的AOP開始。

1  動態代理

    Spring AOP中使用了兩種動態代理,一種是JDK的動態代理,一種CGLIB的動態代理。JDK的動態代理必須指定介面,這些介面都是已經被代理物件實現了的;而CGLIB代理則不需要指定介面。

1.1 JDK動態代理

JDK的動態代理網上有很多資料,這裡只說我自己的理解。

JDK動態代理必須實現InvocationHandler介面,然後通過Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)獲得動態代理物件。

示例:

  View Code

所有方法都會被導向呼叫InvocationHandler介面的唯一的方法invoke,這個就是我們在被代理物件前後插入相關邏輯的地方。

1.2 CGLIB動態代理

1.2.1 CGLIB的代理用法

使用CGLib動態代理,被代理類不需要強制實現介面。

CGLib不能對宣告為final的方法進行代理,因為CGLib原理是動態生成被代理類的子類。

示例:

  View Code

intercept方法中的引數:Object obj為由CGLib動態生成的代理類例項,Method method為被代理類中的方法引用,Object[] args為引數值列表,MethodProxy為生成的代理類對方法的代理引用。

1.2.2 CGLIB的過濾功能

CallbackFilter可以實現不同的方法使用不同的回撥方法,用於分發不同的攔截器。

示例:

  View Code

2  Spring AOP中的動態代理機制

    Spring AOP中的代理根據被代理物件是否實現了介面選擇不同的生成代理物件的方式,即第1部分中的兩個情況。

2.1 JdkDynamicAopProxy

    如果被代理物件實現了需要被代理的介面,則使用JDK的動態代理,在Spring AOP中對應的包裝類為JdkDynamicAopProxy。

    JdkDynamicAopProxy類實現了InvocationHandler介面,將被代理物件和攔截器作為引數傳入,然後生成代理物件。

    當代理物件被呼叫時,JdkDynamicAopProxy的invoke方法作為Proxy物件的回撥函式而被觸發,從而通過invoke的具體實現,來完成對目標物件方法呼叫的攔截或者說功能增強的工作。

    在invoke方法中,設定了包括獲取目標物件、攔截器鏈,同時把這些物件作為輸入,建立了ReflectiveMethodInvocation物件,通過這個ReflectiveMethodInvocation物件來完成對AOP功能實現的封裝。在這個invoke方法中,包含了一個完整的攔截器鏈對目標物件的攔截過程,比如獲得攔截器鏈並對其中的攔截器進行配置,逐個執行攔截器鏈裡的攔截增強,直到最後對目標物件方法的執行。具體可以看原始碼。

  View Code

2.2 CglibAopProxy

    Cglib2AopProxy的intercept回撥方法的實現和JdkDynamicAopProxy的回撥實現是非常類似的,只是在Cglib2AopProxy中構造的是CglibMethodInvocation物件來完成攔截器鏈的呼叫,而在JdkDynamicAopProxy中是通過構造ReflectiveMethodInvocation物件來完成這個功能的。

3 總結

    Spring AOP的核心實現原理就是採用的動態代理,根據被代理物件是否實現了所要被代理的介面這個條件,動態代理會選擇不同的實現方案。本文只是盡我所能簡單的拿著各方資料來了一個彙總,是一個自己的學習總結。對於Spring AOP的設計架構是我下一步的學習目標。

 

參考文獻

1、http://blog.csdn.net/mhmyqn/article/details/48474815

2、《Spring技術內幕:深入解析Spring架構與設計原理》    許文柯