java 动态代理深度学习(Proxy,InvocationHandler),含$Proxy0源码

如何获取动态代理生成的$Proxy0源码。 学习动态代理的过程中没有发现对invoke()方法进行调用的地方,需要看一下jdk的反射中Proxy和生成的代理类$Proxy0的源码。 IUserDao.java package com.company; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lan... 阅读详情



java 动态代理深度学习,

一.相关类及其方法:

java.lang.reflect.Proxy,
Proxy 提供用于创建动态代理类和实例的静态方法.
newProxyInstance()
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序
(详见api文档)

java.lang.reflect.InvocationHandler,
InvocationHandler 是代理实例的调用处理程序 实现的接口。 
invoke()
在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
(详见api文档)

二.源代码:

被代理对象的接口及实现类:
package com.ml.test;

public interface Manager {
public void modify();
}

package com.ml.test;

public class ManagerImpl implements Manager {

@Override
public void modify() {
   System.out.println("*******modify()方法被调用");
}
}

业务代理类:
package com.ml.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class BusinessHandler implements InvocationHandler {

private Object object = null;

public BusinessHandler(Object object) {
   this.object = object;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
   System.out.println("do something before method");

   //不可以调用proxy的toString(),hashCode(),equals()方法或实现了的借口的方法,可以查看下面$proxy0的源码

  //会产生死循环,栈溢出。
   Object ret = method.invoke(this.object, args);
   System.out.println("do something after method");
   return ret;

}
}



客户端类:
package com.ml.test;
import java.lang.reflect.Proxy;
public class Client {

public static void main(String[] args) {
   // 元对象(被代理对象)
   ManagerImpl managerImpl = new ManagerImpl();

   // 业务代理类
   BusinessHandler securityHandler = new BusinessHandler(managerImpl);

   // 获得代理类($Proxy0 extends Proxy implements Manager)的实例.
   Manager managerProxy = (Manager) Proxy.newProxyInstance(managerImpl
     .getClass().getClassLoader(), managerImpl.getClass()
     .getInterfaces(), securityHandler);

   managerProxy.modify();
}
}

三.执行结果:
do something before method
*******modify()方法被调用
do something after method

四.机制分析:

Proxy.(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)做了以下几件事.
(1)根据参数loader和interfaces调用方法 getProxyClass(loader, interfaces)创建代理类$Proxy.
$Proxy0类实现了interfaces的接口,并继承了Proxy类.
(2)实例化$Proxy0并在构造方法中把BusinessHandler传过去,接着$Proxy0调用父类Proxy的构造器,为h赋值,如下:
class Proxy{
   InvocationHandler h=null;
   protected Proxy(InvocationHandler h) {
    this.h = h;
   }
   ...
}



下面是本例的$Proxy0类的源码(好不容易才把它提出来):


你是怎样将代理对象的源码搞出来的???


修改了JRE的源码,打印出字节码,把字节码保存为类文件,并反编译的类文件,就行了。


java.lang.reflect.Proxy.getProxyClass(ClassLoader的类,<?>...) 
  
第501行: 
字节[] proxyClassFile 
  
proxyClassFile就是字节码,反编译字节码就可以了。


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements Manager {

private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;

static {
   try {
    m1 = Class.forName("java.lang.Object").getMethod("equals",
      new Class[] { Class.forName("java.lang.Object") });
    m0 = Class.forName("java.lang.Object").getMethod("hashCode",
      new Class[0]);
    m3 = Class.forName("com.ml.test.Manager").getMethod("modify",
      new Class[0]);
    m2 = Class.forName("java.lang.Object").getMethod("toString",
      new Class[0]);
   } catch (NoSuchMethodException nosuchmethodexception) {
    throw new NoSuchMethodError(nosuchmethodexception.getMessage());
   } catch (ClassNotFoundException classnotfoundexception) {
    throw new NoClassDefFoundError(classnotfoundexception.getMessage());
   }
}

public $Proxy0(InvocationHandler invocationhandler) {
   super(invocationhandler);
}

@Override
public final boolean equals(Object obj) {
   try {
    return ((Boolean) super.h.invoke(this, m1, new Object[] { obj }))
      .booleanValue();
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}

@Override
public final int hashCode() {
   try {
    return ((Integer) super.h.invoke(this, m0, null)).intValue();
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}

public final void modify() {
   try {
    super.h.invoke(this, m3, null);
    return;
   } catch (Error e) {
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}

@Override
public final String toString() {
   try {
    return (String) super.h.invoke(this, m2, null);
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}
}

接着把得到的$Proxy0实例强制转换成Manager.
当执行managerProxy.modify()方法时,就调用了$Proxy0类中的modify()方法.
在modify方法中,调用父类Proxy中的h的invoke()方法.
即InvocationHandler.invoke();


CST Studio Suite安装详细教程(附安装包)CST Studio Suite 2024超详细安装教程 CST Studio Suite 2024安装指南摘要:本文详细介绍了CST Studio Suite 2024电磁仿真软件的下载与安装流程,包含23个图文步骤说明,从解压安装包到配置许可证服务器。重点提示了以管理员身份运行、自定义安装路径等关键步骤,并提供了常见问题解决方案和入门技巧。该软件适用于天线设计、PCB分析等高频电磁场仿真,安装后需通过localhost:27000连接许可证服务器完成激活。 阅读详情

相关推荐

安防相机宽动态(WDR)技术解析:从原理到实战应用

本文深入解析安防相机宽动态(WDR)技术原理,对比多次曝光与DOL-WDR等实现方式,并区分硬件WDR与数字WDR(DWDR)的本质差异。文章重点阐述了WDR在逆光出入口、夜间道路监控等五大典型场景的实战应用与调参技巧,旨在帮助用户根据实际需求正确选择与配置,确保监控系统在复杂光线下清晰成像。

weixin_29191081的博客 427

Proxy和 invocationHandler和invocation的区别

1.Proxy是,Proxy.newProxyInstance()创建出来的 代理对象 什么叫代理对象,就是代理以前的接口,或者实现类的对象 这个对象 也是 接口的实现类类型的,所以Proxy 就是接口类型的 2.invocationHandler 翻译为 调用处理程序,意思是proxy在执行的时候,会调用对应的 handler,去处理 ...

Chen4852010的博客 875

嵌入式定点PID控制器:mrm-pid极简实现与实时控制实践

PID控制器是自动控制领域的基础算法,其核心在于比例、积分、微分三环节的协同调节。在资源受限的嵌入式系统中,传统浮点PID易受时序抖动、内存分配不确定性及FPU依赖影响,难以满足毫秒级确定性响应需求。定点PID通过整数运算替代浮点计算,显著提升执行周期稳定性与跨平台兼容性,成为电机控制、传感器补偿等实时场景的关键技术路径。mrm-pid库以位置式结构、int32_t增益参数、int64_t积分累加器和无动态内存设计,实现了超低开销(12–28 CPU周期)与完全可审计的闭环内核,天然适配Cortex-M系列

weixin_31659095的博客 570

动态代理InvocationHandler和Proxy

java动态代理机制中有两个重要的类和接口InvocationHandler(接口)和Proxy(类),这一个类Proxy和接口InvocationHandler是我们实现动态代理的核心; 1.InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口,每一个proxy代理实例都有一个关联的调用处理程序;在代理实例调用方法时,方法调用被编码分派到调用处理程序的invok...

sc的博客 688

十五天学会Autodesk Inventor,看完这一系列就够了(七),工程图纸

不管哪种绘图软件,二维或三维绘图,最终均需要转换成工程图纸,才能交给现场人员进行制作,这是任一产品图都要经历的过程。那本章开始,我们一起看一下Inventor是如何实现工程图纸?

Crazydoubao的博客 4906

Kettle入门指南:从安装到数据转换实战

本文提供Kettle(Pentaho Data Integration)的完整入门指南,涵盖从Java环境安装、软件配置到核心概念(转换与作业)的详细解析。通过实战案例,手把手教你如何将文本文件数据导出到Excel,并连接MySQL数据库进行数据导入,帮助你快速掌握这一强大ETL工具的基本使用,实现高效数据搬运与转换。

weixin_29266647的博客 448

Java动态代理中的$Proxy0类

转自:http://hi.baidu.com/malecu/blog/item/45d4952b31bc0e27d52af17a.html java 动态代理深度学习,一.相关类及其方法:java.lang.reflect.Proxy,Proxy 提供用于创建动态代理类和实例的静态方法.newProxyInstance()返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定

1073

Delphi开发者必备:CEF4Delphi跨平台浏览器嵌入实战指南(含Lazarus适配)

本文详细介绍了Delphi开发者如何利用CEF4Delphi实现跨平台浏览器嵌入,包括环境配置、Lazarus适配、ARM架构优化及Firemonkey集成等实战技巧。通过Chromium引擎的强大功能,开发者可以轻松为传统桌面应用添加现代浏览器特性,提升多平台开发效率。

weixin_29233333的博客 226

Proxy 动态代理 InvocationHandler CGLIB MD

Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com Proxy 动态代理 InvocationHandler CGLIB MD 目录 目录InvocationHandler ...

weixin_34068198的博客 278

Spring Boot入门(03): 从零开始学习配置文件:掌握YAML和Properties,轻松应对多环境配置管理

在Spring Boot开发中,配置文件是非常重要的。本文将带领你从零开始学习配置文件,掌握YAML和Properties的语法,轻松应对多环境配置管理。无论是开发、测试还是生产环境,你都可以轻松切换不同的配置文件,并且能够灵活修改配置信息。

**My Coding Family** 4万+

YOLOv12创新改进 | 全网独家创新篇、小目标检测改进 | AAAI 2025 | 引入HS-FPN中的HFP和SDP创新点,从频域增强小目标特征,淘汰FPN进行升级,助力YOLOv12有效涨点

本文提出了HS-FPN(高频和空间感知特征金字塔网络),通过HFP(高频感知)模块增强小目标特征,SDP(空间依赖感知)模块捕获像素间空间依赖关系。实验在AI-TOD等小目标数据集上验证了该方法的有效性,相比FPN显著提升检测性能。文章详细介绍了HS-FPN的网络结构、核心代码实现及在YOLOv12中的应用方法,并提供多种改进版本的yaml配置文件,为小目标检测任务提供了有效的解决方案。

Ai缝合怪、助力小伙伴高效发论文 336

java 动态代理深度学习(Proxy,InvocationHandler),含$Proxy0源码(转)

转载: http://hi.baidu.com/malecu/item/9e0edc115cb597a1feded5a0 java 动态代理深度学习, 一.相关类及其方法: java.lang.reflect.Proxy, Proxy 提供用于创建动态代理类和实例的静态方法. newProxyInstance() 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用

y_x_wei的专栏 667

时间序列预测 | Python实现ARIMAX和VARMAX时间序列数据预测

时间序列预测 | Python实现ARIMAX和VARMAX时间序列数据预测 目录时间序列预测 | Python实现ARIMAX和VARMAX时间序列数据预测基本介绍ARIMAXVARVARMAVARMAXSESHWES参考资料 基本介绍 本文介绍ARIMAX、VAR、VARMA和VARMAX基本概念及其Python程序设计。 ARIMAX 具有外源回归量的自回归整合移动平均值(ARIMAX)是 ARIMA 模型的扩展,其还包括外生变量的建模。 外生变量也称为协变量,可以被认为是并行输入序列,其在与

前程算法屋的博客 6688
上一篇: Proxy源码分析
下一篇: mcat配置之server.xml
GetStudyMessages
博客等级 码龄17年 9粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值