今天突然看到動态代理,想仔細研究一下,下面寫一下心得,純屬個人見解,如有不對希望看到的大俠指正。
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多事情的地方
本來想畫個圖說明一下,發現自己畫的的真心不行,還是解釋一下吧:這裡發給原始對象方法的請求被攔截給代理對象(用Proxy new的那個方法生産),代理對象的收到請求後會執行關聯對象中的invoke方法,而在invoke方法中我們可以執行原始對象的方法,大概就是這樣,如果不明白,咱們看下面的代碼。
java代碼 使用者實體類
java代碼 儲存使用者接口
java代碼 接口實作類
java代碼 生成與代理類相關聯的InvocationHandler對象
java代碼 最後是測試類(用的JUnit)
輸出結果:
新人學習,有不對的請多多指教!