欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > java反射、动态代理-invoke方法自动调用笔记

java反射、动态代理-invoke方法自动调用笔记

2025/4/18 19:31:46 来源:https://blog.csdn.net/enthan809882/article/details/147089203  浏览:    关键词:java反射、动态代理-invoke方法自动调用笔记

文章目录

    • invocationHandler和proxy的关系,为什么一定要用proxy的形式呢
      • 方案一 实现类直接调用
      • 方案二 调用处理实现类直接调用
      • 方案三
        • 如何能够看到代理文件呢
        • invoke方法自动调用-$Proxy0代码
    • 其他
      • 文章

上一篇博客概括的做了个笔记,这篇笔记主要记录下invoke自动调用的原理,因为稍微有点绕,也有些内容,所以单独拿出来。

invocationHandler和proxy的关系,为什么一定要用proxy的形式呢

这又是个比较大的话题。
需要看下进化过程。

方案一 实现类直接调用

直接调用,没用到调用处理接口,也没用到proxy。

/* 直接调用 start */
Car car = new Car();
car.run("100米");
/* 直接调用 end */

方案二 调用处理实现类直接调用

用到了调用处理实现类,没用到proxy。

/* invocationHandler调用 start */
Car car = new Car();
TimeInvocationHandler timeInvocationHandler = new TimeInvocationHandler(car);
String[] arg2={"100米"};
try {timeInvocationHandler.invoke(null,Car.class.getMethod("run",String.class),arg2);
} catch (Throwable e) {e.printStackTrace();
}
/* invocationHandler调用 end */

方案三

用到了调用处理实现类,也用到了proxy。

/* proxy调用 start */
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
Car car = new Car();
TimeInvocationHandler timeInvocationHandler = new TimeInvocationHandler(car);
Object o
=Proxy.newProxyInstance(Car.class.getClassLoader(),new Class[]{Vehicle.class},timeInvocationHandler);
Vehicle proxyInstance = (Vehicle)o;
proxyInstance.run("100米");
/* proxy调用 end */
如何能够看到代理文件呢

执行前加上这一行代码:

System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

这样就会生成该class文件,com.sun.proxy.$Proxy0。

invoke方法自动调用-$Proxy0代码

看到代码就一目了然了,原来是$Proxy0实现了业务接口,调用run()方法的时候,再反调h.invoke()

这种机制也不难理解,至于为什么用这种形式实现,直接调用方法不好吗?
主要是这种机制实现了动态代理。

如下代码包名等,个别有省略,补全下即可。

package com.sun.proxy;public final class $Proxy0 extends Proxy implements Vehicle {private static Method m1;private static Method m2;private static Method m3;private static Method m0;public $Proxy0(InvocationHandler var1) throws  {super(var1);}public final boolean equals(Object var1) throws  {try {return (Boolean)super.h.invoke(this, m1, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final String toString() throws  {try {return (String)super.h.invoke(this, m2, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final void run(String var1) throws  {try {super.h.invoke(this, m3, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final int hashCode() throws  {try {return (Integer)super.h.invoke(this, m0, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}static {try {m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));m2 = Class.forName("java.lang.Object").getMethod("toString");
// 这里的包名改下m3 = Class.forName("com.test.Vehicle").getMethod("run", Class.forName("java.lang.String"));m0 = Class.forName("java.lang.Object").getMethod("hashCode");} catch (NoSuchMethodException var2) {throw new NoSuchMethodError(var2.getMessage());} catch (ClassNotFoundException var3) {throw new NoClassDefFoundError(var3.getMessage());}}
}

其他

文章

jdk动态代理介绍及invoke方法自动运行的原因 # 这篇不错,说的比较清楚

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词