載自http://kuangbaoxu.javaeye.com/blog/192804
1. 代理模式主要有兩種:靜態代理和動態代理

2. 靜態代理:

比如要在輸出“HelloWorld”前打印一個字符串“Welcome”

A:先定義一個接口類
1package ttitfly.proxy;    
2   
3public interface HelloWorld {    
4    public void print();    
5//  public void say();    
6}
 
B: 定義一個該接口的實現類

java 代碼
 1package ttitfly.proxy;    
 2   
 3public class HelloWorldImpl implements HelloWorld{    
 4   
 5    public void print(){    
 6        System.out.println("HelloWorld");    
 7    }
    
 8//  public void say(){    
 9//      System.out.println("Say Hello!");    
10//  }    
11}
    
C:定義一個靜態代理類
 1package ttitfly.proxy;    
 2   
 3public class StaticProxy implements HelloWorld{    
 4   
 5    public HelloWorld helloWorld ;    
 6    public StaticProxy(HelloWorld helloWorld){    
 7        this.helloWorld = helloWorld;    
 8    }
    
 9        
10    public void print(){    
11        System.out.println("Welcome");    
12        //相當于回調    
13        helloWorld.print();    
14    }
    
15        
16//  public void say(){    
17//      //相當于回調    
18//      helloWorld.say();    
19//  }    
20}
    
D: 一個測試類:
 1package ttitfly.proxy;    
 2   
 3public class TestStaticProxy {    
 4   
 5    public static void main(String[] args){    
 6        HelloWorld helloWorld = new HelloWorldImpl();    
 7        StaticProxy staticProxy = new StaticProxy(helloWorld);    
 8        staticProxy.print();    
 9            
10//      staticProxy.say();    
11    }
    
12}
    
可以看出靜態代理類有一個很不爽的缺點:當如果接口加一個方法(把上面所有的代碼的注釋給去掉),所有的實現類和代理類里都需要做個實現。這就增加了代碼的復雜度。動態代理就可以避免這個缺點。 
3 。動態代理

動態代理與普通的代理相比較,最大的好處是接口中聲明的所有方法都被轉移到一個集中的方法中處理(invoke),這樣,在接口方法數量比較多的時候,我們可以進行靈活處理,而不需要像靜態代理那樣每一個方法進行中轉。

動態代理類只能代理接口,代理類都需要實現InvocationHandler類,實現invoke方法。該invoke方法就是調用被代理接口的所有方法時需要調用的,該invoke方法返回的值是被代理接口的一個實現類

代理類: 
 1package ttitfly.proxy;        
 2       
 3import java.lang.reflect.InvocationHandler;        
 4import java.lang.reflect.Method;        
 5import java.lang.reflect.Proxy;        
 6//動態代理類只能代理接口,代理類都需要實現InvocationHandler類,實現invoke方法。該invoke方法就是調用被代理接口的所有方法時需要調用的,該invoke方法返回的值是被代理接口的一個實現類        
 7public class DynamicProxy implements InvocationHandler{        
 8            
 9    private Object object;         
10    //綁定關系,也就是關聯到哪個接口(與具體的實現類綁定)的哪些方法將被調用時,執行invoke方法。    
11    //Proxy.newProxyInstance的第三個參數是表明這些被攔截的方法執行時需要執行哪個InvocationHandler的invoke方法    
12    public Object bindRelation(Object object){         
13        this.object = object;        
14        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);         
15    }
         
16    //攔截關聯的這個實現類的方法被調用時將被執行        
17    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {         
18        System.out.println("Welcome");        
19        Object result = method.invoke(object, args);         
20        return result;        
21    }
        
22       
23}
        

測試類:
 1package ttitfly.proxy;        
 2       
 3public class TestDynamicProxy {        
 4    public static void main(String[] args){        
 5        HelloWorld helloWorld = new HelloWorldImpl();        
 6        DynamicProxy dp = new DynamicProxy();        
 7        //在這里綁定的是HelloWorld,也就是HelloWorld是被代理接口。所以綁定關系時,需要傳遞一個HelloWorld的實現類的實例化對象。        
 8        HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld);         
 9        helloWorld1.print();         
10        helloWorld1.say();        
11            
12        //helloWorld2將不被攔截    
13        HelloWorld helloWorld2 = new HelloWorldImpl();    
14        helloWorld2.print();         
15        helloWorld2.say();    
16            
17    }
        
18}
        
在測試類里調用實現類的print和say方法,因為代理類里代理了HelloWorld的所有方法。所以就不需要像靜態代理類那樣一一實現了。
[本來想自己寫個類似的東西,不過發現javaeye的這篇寫的已經很好了.轉載過來學習一下.
 javaeye的代碼copy功能真好用!.]