天天看點

java動态代理DynamicProxy學習

          今天突然看到動态代理,想仔細研究一下,下面寫一下心得,純屬個人見解,如有不對希望看到的大俠指正。

1、首先說一下什麼是動态代理以及動态代理的作用和應用場景(總結一下網上看到的),動态代理其實就是在程式運作期對請求(如方法、消息)做一些特殊的處理(如事務管理、記錄日志),增加了程式的靈活性,如AOP,其實請求攔截下來了我們可以做任何我們想做的事情。

2、動态代理的實作方式:第一種是接口實作,第二種是繼承原來的類(cglib)我這裡寫的是用接口的實作方式

3、知識點涉及到一個接口InvocationHandler 一個類Proxy

    從java API中可以看到介紹大緻為

 3.1  interface InvocationHandler 

   Object invoke(Object proxy, Method method, Object[] args) 

   在代理執行個體上處理方法調用并傳回結果。在與方法關聯的代理執行個體上調用方法時,将在調用處理程式上調用此方法。 

   參數:

proxy - 在其上調用方法的代理執行個體

method - 對應于在代理執行個體上調用的接口方法的 Method 執行個體。Method 對象的聲明類将是在其中聲明方法的接口,該接口可以是代理類賴以繼承方法的代理接口的超接口。

args - 包含傳入代理執行個體上方法調用的參數值的對象數組,如果接口方法不使用參數,則為 null。基本類型的參數被包裝在适當基本

包裝器類(如 java.lang.Integer 或 java.lang.Boolean)的執行個體中。 

傳回:

從代理執行個體的方法調用傳回的值。如果接口方法的聲明傳回類型是基本類型,則此方法傳回的值一定是相應基本包裝對象類的執行個體;否則,

它一定是可配置設定到聲明傳回類型的類型。如果此方法傳回的值為 null 并且接口方法的傳回類型是基本類型,

則代理執行個體上的方法調用将抛出 NullPointerException。否則,如果此方法傳回的值與上述接口方法的聲明傳回類型不相容,則代理執行個體上的方法調用将抛出 

3.2 class Proxy 

真正表示動态代理的類,提供兩個靜态方法:  

Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface) 

用來産生代理類,參數要提供interface數組,它會生成這些interface的“虛拟實作”, 

用來冒充真實的對象。 

Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 

産生代理對象,多了InvocationHandler參數(隻是InvocationHandler接口的實作類), 

它與代理對象關聯,當請求分發到代理對象後,會自動執行h.invoke(...)方法, 

invoke方法就是我們用來做N多事情的地方

java動态代理DynamicProxy學習

本來想畫個圖說明一下,發現自己畫的的真心不行,還是解釋一下吧:這裡發給原始對象方法的請求被攔截給代理對象(用Proxy new的那個方法生産),代理對象的收到請求後會執行關聯對象中的invoke方法,而在invoke方法中我們可以執行原始對象的方法,大概就是這樣,如果不明白,咱們看下面的代碼。

 java代碼 使用者實體類

java動态代理DynamicProxy學習

java代碼 儲存使用者接口

java動态代理DynamicProxy學習

java代碼 接口實作類

java動态代理DynamicProxy學習

java代碼  生成與代理類相關聯的InvocationHandler對象 

java動态代理DynamicProxy學習

java代碼 最後是測試類(用的JUnit)

java動态代理DynamicProxy學習

輸出結果:

java動态代理DynamicProxy學習

新人學習,有不對的請多多指教!