Java-Note-对动态代理的一些理解

动态代理可以动态的创建代理并动态地处理对所代理方法的调用. 在动态代理上所做的所有调用都会被重定向到单一的调用处理器(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
27
28
29
30
31
32
33
34
35
36
37
38
class DynamicProxyHandler implements InvocationHandler {
private Object proxied;

public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("*** proxy: " + proxy.getClass() + ", method: " + method + ", args: " + args);
if (args != null) {
for (Object arg : args) {
System.out.println(" " + arg);
}
}
Object result = method.invoke(proxied, args);
System.out.println("proxy info: " + proxy.toString());
return result;
}
}

public class SimpleDynamicProxy {
public static void consumer(Interface iface) {
iface.doSomething();
iface.somethingElse("bonobo");
}

public static void main(String[] args) {
RealObject real = new RealObject();
consumer(real);
Interface proxy = (Interface) Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[]{Interface.class},
new DynamicProxyHandler(real)
);
consumer(proxy);
}
}

在例子中调用proxy的方法如doSomething()会被指向invoke(), 而如果在invoke()中再调用proxy的方法如toString()时,会陷入循环调用的陷阱, 进而抛出Stack Overflow的错误.

参考文献: Thinking in Java Fourth Edition