Java動態代理

 

動態代理是代理模式的實現,在程序運行時,運用反射機制動態創建而成。Java動態代理是Java語言世界的動態代理。

爲了更好地理解動態代理,我們先講述一下代理模式。

代理模式一種軟件設計模式, 是代理類與委託類有同樣的接口。代理類主要負責爲委託類預處理消息、過濾消息、把消息轉發給委託類,以及事後處理消息等。

如下面代理模式比較通用的類圖,Proxy是代理類,RealSubject是目標類,它們實現了同樣的接口。也就是說Proxy類可以用在RealSubject使用的地方。

 image_thumb3

動態代理相比靜態代理的不同在於:靜態代理是由程序員創建或特定工具自動生成源代碼,再對其編譯,在程序運行前,代理類就已經存在了。在Java程序中,也就是代理類的.class文件就已經存在了。 而動態代理的代理類是在程序運行時,運用反射機制動態創建而成。

Java動態代理的兩種實現:JDK動態代理和CGLib動態代理

  • JDK 動態代理

JDK動態代理是Java 原生的動態代理方法,不需要依賴任何第三方庫。通過java.lang.reflect.Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法來動態生成代理類。該方法有三個參數:
       loader: 加載代理類的ClassLoader
       interfaces: 代理類代理的目標類的接口
       h:代理類的攔截器,通過定義實現InvocationHandler接口的類來實現自己的攔截器。

生成的代理類,類名如$ProxyXXX。如下面類圖, 代理類$ProxyXXX繼承java.lang.reflect.Proxy,並實現一個或者多個目標類的接口。在java.lang.reflect.Proxy類中有一個InvocationHandler類型的屬性h,表示用戶定義的攔截器。MyInvocationHandler是我們自定義的一個攔截器,其中有一個myTargetObject屬性表示目標對象(這個不是必須的,但如果需要代理對象,我們可以將代理對象放在這),還有一個invoke方法,該方法是覆蓋了接口中的invoke方法,當調用代理類的方法時,會調用攔截器的invoke方法。
     

Main_thumb1

  • CGLib 動態代理

CGLib 動態代理是通過使用一個小而快的字節處理框架ASM(Java字節碼操控框架)來轉換字節碼並生成動態代理需要的類。CGLib除了生成我們需要的代理類,還會生成一些輔助類。

生成的代理圖如下面類圖,ObjectClass是我們的目標類,ObjectClass$$EhanceByCGLib$$****是動態生成的代理類,其中有CGLib$CALLBACK_X屬性是攔截器。MyMethodInterceptor是我們自己實現的攔截器,其中有一個targetObject屬性是代理的目標對象(這個不是必須的,但如果需要代理對象,我們可以將代理對象放在這)。而intercept方法是覆蓋的MethodIntercepter的方法, 當調用代理類的方法時,會調用攔截器的intercept 方法。

ClassDiagram1_thumb2

發佈了28 篇原創文章 · 獲贊 16 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章