載自http://kuangbaoxu.javaeye.com/blog/192804
1. 代理模式主要有兩種:靜態(tài)代理和動(dòng)態(tài)代理
2. 靜態(tài)代理:
比如要在輸出“HelloWorld”前打印一個(gè)字符串“Welcome”
A:先定義一個(gè)接口類
java 代碼
3 。動(dòng)態(tài)代理
動(dòng)態(tài)代理與普通的代理相比較,最大的好處是接口中聲明的所有方法都被轉(zhuǎn)移到一個(gè)集中的方法中處理(invoke),這樣,在接口方法數(shù)量比較多的時(shí)候,我們可以進(jìn)行靈活處理,而不需要像靜態(tài)代理那樣每一個(gè)方法進(jìn)行中轉(zhuǎn)。
動(dòng)態(tài)代理類只能代理接口,代理類都需要實(shí)現(xiàn)InvocationHandler類,實(shí)現(xiàn)invoke方法。該invoke方法就是調(diào)用被代理接口的所有方法時(shí)需要調(diào)用的,該invoke方法返回的值是被代理接口的一個(gè)實(shí)現(xiàn)類
代理類:
測(cè)試類:
[本來想自己寫個(gè)類似的東西,不過發(fā)現(xiàn)javaeye的這篇寫的已經(jīng)很好了.轉(zhuǎn)載過來學(xué)習(xí)一下.
javaeye的代碼copy功能真好用!.]
1. 代理模式主要有兩種:靜態(tài)代理和動(dòng)態(tài)代理
2. 靜態(tài)代理:
比如要在輸出“HelloWorld”前打印一個(gè)字符串“Welcome”
A:先定義一個(gè)接口類
1
package ttitfly.proxy;
2
3
public interface HelloWorld {
4
public void print();
5
// public void say();
6
}
B: 定義一個(gè)該接口的實(shí)現(xiàn)類 
2

3

4

5

6

java 代碼
1
package ttitfly.proxy;
2
3
public 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:定義一個(gè)靜態(tài)代理類 
2

3

4

5

6

7

8

9

10

11

1
package ttitfly.proxy;
2
3
public 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
//相當(dāng)于回調(diào)
13
helloWorld.print();
14
}
15
16
// public void say(){
17
// //相當(dāng)于回調(diào)
18
// helloWorld.say();
19
// }
20
}
D: 一個(gè)測(cè)試類: 
2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

1
package ttitfly.proxy;
2
3
public 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
}
可以看出靜態(tài)代理類有一個(gè)很不爽的缺點(diǎn):當(dāng)如果接口加一個(gè)方法(把上面所有的代碼的注釋給去掉),所有的實(shí)現(xiàn)類和代理類里都需要做個(gè)實(shí)現(xiàn)。這就增加了代碼的復(fù)雜度。動(dòng)態(tài)代理就可以避免這個(gè)缺點(diǎn)。 
2

3

4

5

6

7

8

9

10

11

12

3 。動(dòng)態(tài)代理
動(dòng)態(tài)代理與普通的代理相比較,最大的好處是接口中聲明的所有方法都被轉(zhuǎn)移到一個(gè)集中的方法中處理(invoke),這樣,在接口方法數(shù)量比較多的時(shí)候,我們可以進(jìn)行靈活處理,而不需要像靜態(tài)代理那樣每一個(gè)方法進(jìn)行中轉(zhuǎn)。
動(dòng)態(tài)代理類只能代理接口,代理類都需要實(shí)現(xiàn)InvocationHandler類,實(shí)現(xiàn)invoke方法。該invoke方法就是調(diào)用被代理接口的所有方法時(shí)需要調(diào)用的,該invoke方法返回的值是被代理接口的一個(gè)實(shí)現(xiàn)類
代理類:
1
package ttitfly.proxy;
2
3
import java.lang.reflect.InvocationHandler;
4
import java.lang.reflect.Method;
5
import java.lang.reflect.Proxy;
6
//動(dòng)態(tài)代理類只能代理接口,代理類都需要實(shí)現(xiàn)InvocationHandler類,實(shí)現(xiàn)invoke方法。該invoke方法就是調(diào)用被代理接口的所有方法時(shí)需要調(diào)用的,該invoke方法返回的值是被代理接口的一個(gè)實(shí)現(xiàn)類
7
public class DynamicProxy implements InvocationHandler{
8
9
private Object object;
10
//綁定關(guān)系,也就是關(guān)聯(lián)到哪個(gè)接口(與具體的實(shí)現(xiàn)類綁定)的哪些方法將被調(diào)用時(shí),執(zhí)行invoke方法。
11
//Proxy.newProxyInstance的第三個(gè)參數(shù)是表明這些被攔截的方法執(zhí)行時(shí)需要執(zhí)行哪個(gè)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
//攔截關(guān)聯(lián)的這個(gè)實(shí)現(xiàn)類的方法被調(diào)用時(shí)將被執(zhí)行
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
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

測(cè)試類:
1
package ttitfly.proxy;
2
3
public class TestDynamicProxy {
4
public static void main(String[] args){
5
HelloWorld helloWorld = new HelloWorldImpl();
6
DynamicProxy dp = new DynamicProxy();
7
//在這里綁定的是HelloWorld,也就是HelloWorld是被代理接口。所以綁定關(guān)系時(shí),需要傳遞一個(gè)HelloWorld的實(shí)現(xiàn)類的實(shí)例化對(duì)象。
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
}
在測(cè)試類里調(diào)用實(shí)現(xiàn)類的print和say方法,因?yàn)榇眍惱锎砹薍elloWorld的所有方法。所以就不需要像靜態(tài)代理類那樣一一實(shí)現(xiàn)了。 
2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

[本來想自己寫個(gè)類似的東西,不過發(fā)現(xiàn)javaeye的這篇寫的已經(jīng)很好了.轉(zhuǎn)載過來學(xué)習(xí)一下.
javaeye的代碼copy功能真好用!.]
..多看幾次吧..