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