Java中代理(Proxy)的实现机制

看TIJ的代理看得有点晕,其中有一段代码如下。(print是包装了下的System.out.println)

package TypeInfo;
// typeinfo/SimpleDynamicProxy23.java
// TIJ4 Chapter Typeinfo, Exercise 23, page 598
// Inside invoke() in SimpleDynamicProxy.java, try to print the proxy argument and explain
// what happens.
import java.lang.reflect.*;

interface Interface {
void doSomething();
void somethingElse(String arg);
}

class RealObject implements Interface {
public void doSomething() { print("doSomething"); }
public void somethingElse(String arg) {
print("somethingElse " + arg);
}
}

class DynamicProxyHandler implements InvocationHandler {
private Object proxied;
public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/* 
* trying to print proxy leads to:
* StackOverFlowError 
* at AbstractStringBuilder.(Unknown Source)
* at StringBuilder.(Unknown Source)
* at DynamicProxyHandler.invoke(SimpleDynamicProxy23.java)
* at $Proxy0.toString(Unknown Source)
* at String.valueOf(Unknown Source)
* at StrinbBuilcer.append(Unknown Source)
* at DynamicProxyHandler.invoke(SimpleDynamicProxy23.java), etc,
* probably due to infinite recursion because calls to toString()
* are passed repeatedly back to this invoke method
/
// System.out.println("proxy: " + proxy); // error
System.out.println("
*** proxy: " + proxy.getClass() +
", method: " + method + ", args: " + args);
if(args != null)
for(Object arg : args)
System.out.println(" " + args);
return method.invoke(proxied, args);
}
}


代码比较容易看懂,但是其中的内在机制就很隐晦。调试时发现,consumer中调用Interface的方法后程序流直接就跳入了invoke。这是由什么机制决定的?换言之,在consumer中对接口Interface的方法的调用是如何转交给DynamicProxyHandler的invoke方法的?
书中有一句话:“在invoke()内部,在代理上调用方法时需要格外当心,因为对接口的调用将被重定向为对代理的调用。”这句解释了注释掉的“// System.out.println("proxy: " + proxy); // error”的错误是因为引起了无限递归(很空洞的解释,具体怎样引起?)invoke的第一个参数proxy是什么类型?
希望大家不吝赐教。3Q!

凤凰求蛊
浏览 795回答 4
4回答

元芳怎么了

调试时发现,consumer中调用Interface的方法后程序流直接就跳入了invoke。这是由什么机制决定的?——————Interface proxy = (Interface)Proxy.newProxyInstance(Interface.class.getClassLoader(),new Class[]{ Interface.class },new DynamicProxyHandler(real));consumer(proxy);这些代码决定的。 Proxy.newProxyInstance代码是JDK的代码,楼主是想了解JDK的底层实现...?要了解这个, 就要了解JDK类字节码的生成, 了解了类字节码的生成就要了解类的加载器...真没必要去纠结JDK的底层实现...
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java