为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

凤凰求蛊 2019-03-14 22:19:00
看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); // errorSystem.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!
查看完整描述

4 回答

?
元芳怎么了

TA贡献1798条经验 获得超7个赞

调试时发现,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的底层实现...


查看完整回答
反对 回复 2019-04-29
  • 4 回答
  • 0 关注
  • 794 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信