代理模式,即ProxyPattern,java常用設計模式之一,動态代理實作了著名的AOP思想。代理模式的思想是為了提供額外的處理或者不同的操作而在實際對象與調用者之間插入一個代理對象。這些額外的操作通常需要與實際對象進行通信。
通俗的講,可以拿到現實中來舉例,可能說的并不準确,比如,蘋果出了一款iphone手機,拿到中國交給代理商來賣,如聯通、電信,就是所謂的定制機,聯通電信又給iphone手機植入了一些軟體,再賣給使用者。我們最後買到的手機就是代理商處理過的。
靜态代理很好了解,代碼類似如下:
原類:
package staticProxy;public class Object { public void service() { // do something }}
代理類:
package staticProxy;public class ProxyObject { private staticProxy.Object obj; public ProxyObject(staticProxy.Object obj) { this.obj = obj; } public void service() { // do something this.obj.service(); }}
靜态代理需要對每個原類建立一個代理類,這樣做需要代理的情況少的話還可以接受,如果多的話,就無法接受了,是以我們需要一種動态建立代理類的方式。
Java支援動态代理,可以在運作期根據原對象來動态建立代理對象。有兩種方式可以實作動态代理,一種是通過JDK Proxy,另一種是第三方類庫CGLIB,前者得到的代理對象是實作和原類相同的接口,後者得到的是繼承自原類。下面主要介紹的是JDK Proxy。
Proxy類中有個newProxyInstance方法,可以通過該方法得到代理對象,該方法有三個參數:
ClassLoader loader:原類的類加載器;
Class[] interfaces:原類實作的接口清單;
InvocationHandler handler:指派方法調用的調用處理程式。
調用該方法建立代理對象時,會把InvocationHandler傳入$Proxy内,并根據相應接口生成方法,每個方法内都調用InvocationHandler中的invoke方法,在invoke方法中執行相應方法。

Advice.java,增強類,用于建立代理對象時增強功能。
public class Advice { /** 前置增強 */ public void beforeMethod() { System.out.println("前置增強"); } /** 後置增強 */ public void afterMethod() { System.out.println("後置增強"); } /** 異常增強 */ public void catchMethod() { System.out.println("異常增強"); } /** 最後執行增強 */ public void finallyMethod() { System.out.println("最後增強"); }}
ProxyFactory.java,代理類工廠,用于産生代理對象。
public class ProxyFactory { /** 代理類的增強對象 */ private Advice advice; /** 代理的目标對象 */ private Object target; public ProxyFactory() {} public ProxyFactory(Advice advice, Object target) { this.advice = advice; this.target = target; } /** * 得到代理對象 * @return */ public Object getProxy() { Object proxy = Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(),new InvocationHandler() { /** * 代理對象需要執行的方法 */ public Object invoke(Object proxy, Method method, Object[] args) { Object result = null; advice.beforeMethod(); try { result = method.invoke(target, args); advice.afterMethod(); } catch (Exception e) { advice.catchMethod(); } finally { advice.finallyMethod(); } return result; } }); return proxy; } public void setAdvice(Advice advice) { this.advice = advice; } public void setTarget(Object target) { this.target = target; }}
ITest.java,目标對象接口。
public interface ITest { void test();}
Test.java,目标對象類。
public class Test implements ITest { public void test() { System.out.println("目标對象"); } public static void main(String[] args) { ProxyFactory pf = new ProxyFactory(new Advice(), new Test()); ITest test = (ITest) pf.getProxy(); test.test(); }}
輸出結果:
前置增強目标對象後置增強最後增強
動态代理實作了AOP思想,AOP彌補了OOP的不足。本篇主要介紹的是jdk proxy動态代理的使用方式,對AOP沒有特意說明。