java的動態代理在接java的api上有說明,這里就不寫了。我理解的代理:
對特定接口中特定方法的功能進行擴展,這就是代理。代理是通過代理實例關聯的調用處理程序對象調用方法。
下面通過一個例子看一下:
接口:
1
2
3
4
5
6
7
|
public interface Num { void show(); int getNum(); int getProduct( int x); } |
實現類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public class MyNum implements Num { @Override public int getNum() { return 3 ; } @Override public int getProduct( int x) { return x; } @Override public void show() { System.out.println( "底層方法打印數字99" ); } } |
先看一下Method中的invoke方法在api中是怎么描述的
就是說調用處理程序對接口的實現類對象調用Method對象表示的底層方法。
第一種實現代理的方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
public class NumProxy { private Object num; //通過構造方法構造接口的實現類對象 public NumProxy(Object num) { this .num = num; } public Object getNumByProxy(){ Object numProxy = Proxy.newProxyInstance(num.getClass().getClassLoader(), new Class[]{Num. class }, new InvocationHandler() { /** * method: 對應于在代理實例上調用的接口方法的 Method 實例。我理解的就是被代理的真實方法實例 * args: 我理解的是真實方法的參數數組 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null ; System.out.println( "在方法之前開始記錄" ); String methodName = method.getName(); if ( "getProduct" .equals(methodName)){ obj = method.invoke(num, args); obj = (Integer) obj * 2 ; System.out.println( "proxy: getProduct()結束" ); } else if ( "show" .equals(methodName)){ obj = method.invoke(num, args); System.out.println( "proxy: show()結束" ); } return obj; } }); return numProxy; } } |
第二種實現代理的方式:通過實現InvocationHandler接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class NumProxyImpl implements InvocationHandler { //這里我把接口類型具體化了, 沒有寫成Object private Num num; public NumProxyImpl(Num num){ this .num = num; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null ; String methodName = method.getName(); if ( "getProduct" .equals(methodName)){ System.out.println( "proxy: getProduct()開始" ); obj = method.invoke(num, args); obj = (Integer) obj * 2 ; System.out.println( "proxy: getProduct()結束" ); } else if ( "show" .equals(methodName)){ System.out.println( "proxy: show()開始" ); obj = method.invoke(num, args); System.out.println( "proxy: show()結束" ); } return obj; } } |
測試代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class TestNum { public static void main(String[] args) { //兩種方式一起測試 NumProxy np = new NumProxy( new MyNum()); Num numProxy = (Num) np.getNumByProxy(); int x = numProxy.getProduct( 2 ); System.out.println(x); numProxy.show(); System.out.println( "----------------" ); NumProxyImpl npi = new NumProxyImpl( new MyNum()); Num numPro = (Num) Proxy.newProxyInstance(Num. class .getClassLoader(), new Class[]{Num. class }, npi); int n = numPro.getProduct( 3 ); System.out.println(n); numPro.show(); } } |
控制臺結果:
第二種方式有點小疑惑,不知道大家有沒有,那就是并沒有顯示的調用NumProxyImpl中的invoke方法,可是卻執行了,嗯嗯,這個自己下去看一下啊
不想麻煩的只需要記住就行了。
比如編碼的處理就可以用到代理,下次寫個例子。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/pdzbokey/p/6114509.html