范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

基于Javassist实现Java动态代理

  阅读完本文你能 get 到的知识点什么是 JavassistJDK 动态代理使用 Javassist 实现和 JDK 一样的效果什么是Javassist
  很多同学估计会对这个词有点陌生,但随着你关注的博主越来越多,知道的也越来越多,马上这篇文章就带你走进 Javassist 的世界
  Javassist 和 ASM 一样是操作字节码的框架, Javassist 诞生于 1999 年,多少有点年头
  使用 Javassist 可以在运行时定义一个新类,可以在 JVM 加载类文件时修改类文件
  而且 Javassist 提供不同类型的API: 源码级别 和 字节码级别
  本文使用源码级别的 API ,所以你甚至可以在不懂字节码的前提下使用它,入手相对简单
  但在性能上略逊于 ASMJDK 动态代理
  话不多说,先来回顾一下我们平时是怎么使用 JDK 动态代理的Proxy
  JDK 提供一个类 Proxy 用于生成代理类
  调用类方法 newProxyInstance,传入的参数ClassLoader loader : 定义代理类的类加载器Class<?>[] interfaces : 代理类需要实现的所有接口InvocationHandler h : 调用处理程序,方法调用都会分派到这里
  InvocationHandler
  InvocationHandler 是一个接口类,定义了调用方法Object proxy : 生成的代理对象Method method : 接口方法实例Object[] args : 方法调用中传递的参数值
  如何调用
  调用 Proxy.newProxyInstance 生成代理对象, 传入参数接口InvocationHandler实现类的对象处理代理的逻辑
  代码设计
  在动手写代码之前,我们先花几分钟在脑海中设想一下我们需要生成的代理类是什么样子的?
  这里先揭晓了
  假设我们定义了一个接口类 LoginService定义的接口类
  那么我们需要生成一个大概是这样的代理类首先必须得实现了定义的接口 LoginService接口的所有方法实现都调用都代理到 InvocationHandler 中
  几个重要的类
  从上面生成的代理类入手,我们生成的类
  继承了父类 MObject
  实现了需要代理的接口 LoginService
  生成了类成员变量 LoginService_0, 这个对应 接口的定义的方法
  实现了需要代理的接口方法 login
  还有带参数 MInvocationHandler 的构造方法MObject
  MObject 是生成的代理类需要继承的父类,它的作用是存储了 MInvocationHandler(处理程序接口)
  MInvocationHandler
  同 JDK 自带的接口 InvocationHandler ,用于实现代理方法的处理逻辑
  MProxy
  同 JDK 自带的类 Proxy
  提供生成代理对象的方法 newProxyInstance
  编码开始
  在经过代码设计之后,我们的脑海里应该有思路了,那就开始动手了
  整个过程中比较重要的部分应该就是 MProxy 类了
  在 MProxy 里面我们需要实现两大功能:生成代理类字节码根据字节码生成对象生成代理类字节码生成代理类名称生成空类给类设置需要实现的接口添加类成员变量实现接口方法
  生成代理类名称
  这一步相对简单,为了防止生成的代理类重名
  这里拼接了所有需要代理的接口全限定类名,通过字符串 "_" 连接
  生成空类
  首先我们需要根据新的类名生成一个空的类,注意类名不要重复了,不然会污染了原有的类
  ClassPool : 类池,存储所有类的信息,会将类名->类信息 存储到 HashTable 里, 可通过 ClassPool.getDefault() 获取实例CtClass: 代表一个类classPool.makeClass : 生成新的类给类设置需要实现的接口
  这里同样通过 ClassPool 的 get 方法获取到所有传入接口的 CtClass 定义
  再调用 setInterfaces 方法给生成的类设置多个接口
  添加类成员变量
  因为我们调用 MInvocationHandler 的 invoke 方法时需要传入的第二个参数是被代理方法的 Method实例
  所以将这个方法的存储到类成员变量中
  CtField 代表着一个变量
  传入类型、变量名 生成一个 CtField 实例
  通过 setModifiers 方法设置变量的修饰符为 static + private
  因为这里还要设置变量的值
  调用 getFieldInitCode 生成初始化代码
  为了获取 Method 对象 ,这里生成了反射的代码去获取
  实例: Class.forName(类名).getMethod(方法名, Class<?>... 方法的参数类型);
  生成了类成员变量之后,接下来该到实现接口的方法了实现接口方法
  这里需要实现接口的方法
  可以通过 CtNewMethod.copy 方法去拷贝需要实现的方法,不要直接使用原来的 CtMethod , 防止污染
  拿到新的 CtMethod ,我们需要设置它的方法体、设置修饰符为 public
  重点来看看怎么生成方法体代码
  这里根据方法返回的类型调用不同的方法void : 没有返回值的 调用 getMethodBodyCodeByVoid基本数据类型 : 调用 getMethodBodyCodeByPrimitive其它类型 : 调用 getMethodBodyCode
  那按顺序来看,不需要返回值的
  那我们需要生成的代码是长这样的
  super.h.invoke(this, 对应的类成员变量, new Object[]{方法参数});
  这个有个语法需要知道: $0 代表这方法的第一个参数,懂字节码的应该知道非构造方法的第一个入参是 一个隐式的 this ,指向对象本身
  new Object[]{} 里面就可以用 11 12 代表着方法的参数了
  返回值是基本数据类型的,需要调用调用包装类型对应的拆箱方法 如
  Boolean.parseBoolean()
  所以和上面生成步骤的区别在于 前后生成了对于基本类型的 parse 代码
  最后的返回其它类型的也比较简单
  直接生成强转的代码 如 (String)
  以上步骤走完,前期准备工作算是做完了,接下来就要根据生成的字节码来实例化对象了根据字节码生成对象
  要根据字节码来生成对象,第一步我们需要编写自定义的类加载器,通过类加载器加载字节码编写自定义加载器 MClassLoader ,继承类 ClassLoader提供 add 方法将类名映射到对应的字节数组重写 ClassLoader 类的 findClass 方法,使用我们生成的字节数组生成类
  在 MProxy 中调用 MClassLoader 加载并实例化对象加载类 mClassLoader.loadClass(clasName)获取带 MInvocationHandler 参数类型的构造实例化对象 constructor.newInstance(h)
  效果演示
  好了,上面的代码已经编写完了,那么现在就来对比一下 JDK 自带的 Proxy 和我们自己实现的 Proxy 的效果我们定义一个需要代理的接口 LoginService
  这里按照 Java 的基本数据类型 以及它们对应的包装类 定义了16个接口方法
  分别实现了代理类 CusMInvocationHandler 和 CusJdkInvocationHandler
  这两个代理类的实现是一样的
  区别在于实现的接口一个是我们定义的 MInvocationHandler
  另一个是 JDK 的 InvocationHandler
  执行入口类
  Main 类分别生成了 Proxy 和 MProxy 的代理对象
  然后执行代理对象的各个方法
  来看看实现的效果,左边是 JDK 的动态代理,右边是使用 Javassist 实现的动态代理
  作者:MinXie
  链接:https://juejin.cn/post/7168030376080703495

为什么剖腹产的人越来越多,人们不愿意顺产?这个问题,其实人们是走入了误区,想啊,宇宙,自然界及万物都有它的自然规律和界定,为什么说天命难违,顺其自然繁衍生息,新陈代谢等等,这就是自然规律,再正常不过了,如人生孩子顺产是对的亮剑里的参谋长张大彪后来为什么突然不见了?会授少将衔吗?谢谢邀请。亮剑里张大彪由营长干到参谋长,是李云龙的得力助手,但是,后来,李云龙升为上学,升为军长,再没有张大彪的戏。张大彪突然不见了,这是为什么?这个问题很简单,是剧情的需要,李云你经历过最穷最落魄时,是什么样子?小时候的记忆就是穷,我父亲是在钱塘江挖沙的,有一天沙船撞了下沉了,我父亲会游泳,不幸中万幸,他回来了。从此我们成了村里最穷的人,赔了一条船。80年代的上万的船,放现在上百万或者几十60多,退休了,想买一辆SUV,有何推荐?60多,退休了,买一辆SUV,有何推荐?我从这个阶段过来过,我来帮你推荐。退休了想买一辆SUV,我觉得你这个买车选择比较好。车是用来用的。买SUV这类车平时可以家用,改装一下就可以北京周边游怎么玩儿比较好?这样玩你试试,天黑都不想回家?都不用出六环,有水有树林,露营野餐,爽歪歪给北京周边嗯,我大头地方我也去过了,反正外地人来吃吗,呵呵呵,个人觉得好沉66号公路的那个嗯嗯那个什么什么什火箭升空掉落的碎片是什么,对飞行有没有影响?这两年随着航天的发展兴盛,不光涌现出很多民营航天公司,而且很多火箭的发射也变得越来越透明,会直接选择发射直播的方式让民众亲身感受火箭发射的魅力。不过在有的时候我们会在火箭发射刚点火站在月球上,用足够大的望远镜看地球,能看到地球的快速转动吗?足够大的望远镜是可以的,但是这个望远镜肯定大到人举不起来,是建筑那么大。在月球上直接看地球是下图这样的效果。也就相当于在地球上看月球,比月球大那么两圈的样子。望远镜的分辨率要达到看摩托罗拉新旗舰三千元,百万跑分。你觉得可以购买吗?事件回顾2021年12月9日晚上730分,联想正式首发摩托罗拉edgeX30。可能很多人觉都忘记摩托罗拉了,甚至这手机型号听着都拗口。但这都不重要,只需要记住两点就好了1这款手机首为什么外地人去新疆总会长胖,新疆菜的分量为什么这么大?为什么外地人去新疆总会长胖,因为新疆是肉食者的天堂,新疆菜又比较油腻,加上新疆人爱吃牛羊肉和面食。而外地人平时吃的比较清淡,吃肉远没有新疆人多,所以来了新疆,猛吃新疆饭菜,就很容易实体店大批倒闭,直播带货一个人销售几个亿,直播带货该不该上税?要纳税,直播带货就是销售行为,所以肯定要交税的。可能目前的体制,对这类营销模式,没有很好的计税模式,但长期来看,肯定是往税收方向去的。必须上税,不然真的对不起开实体店的,大家都是创恒大董事长要是一直补不上亏空的钱,会被判刑吗?采取的措施是?他没有亏,只是把可流动的资金变成了流动困难的房子,由于加杠杆他不止是把自己的钱变成了房子,而且把很多别人的钱主要是银行的钱也变成了流动困难的房子,正常情况下,钱变成房子是增值了的,
如何参加Apple的iOS内测?你可能不知道有内测目前最新的iOS版本是16。3。那下一个版本是什么?有哪些功能?其实安装beta版就足够了。下文为你提供使用beta版iOS的2个方法iOS16。3一上官网既然是Apple的iOS58零基础Python到全栈八进制与十进制互相转换我们上一章讲了二进制与是进制的互相转换,这章我们讲讲八进制怎么转化成十进制。八进制就有8个符号,分别是01234567,先来看一个八进制数,234。我们现在要把它转成十进制,方法还微星B760MMORTARMAXWIFI装机大口径加持的迫击炮主板是何体验?前言年初的时候,我对微星B760MMORTARMAXWIFI进行了一个开箱展示,发现该主板延续了之前上一代产品的精髓可对12代非K处理器进行超频。于是,今天我开始对着这块主板搞事情按压升降四面取电,公牛推出迷你气动升降插座插座是每家每户必不可少的电力延伸设备,根据不同用途需求已诞生出多种形态,有扁平型修长型魔方型收纳盒转接座等,虽然形态各异但都会额外占据空间,扰乱整洁的桌面布局。近日,插座行业知名品2022年度回顾之CPU篇英特尔平稳过渡13代酷睿,AMD大力推进AM5平台2022年对于业界来说,上半年和下半年是完全不同的两种市况,一半是海水,一半是火焰。上半年继续受到新冠疫情的影响,以及2020年就已出现的供应短缺问题,PC市场基本延续了去年的态势SQLSERVER事务日志的LSN到底是什么?一背景1。讲故事大家都知道数据库应用程序它天生需要围绕着数据文件打转,诸如包含数据的。mdf,事务日志的。ldf,很多时候深入了解这两类文件的合成原理,差不多对数据库就能理解一半了苗苗首次穿中国嫁衣,雍容华贵撞脸章子怡,郑恺的气质有点配不上文忍耐娱乐最新一期的妻子的浪漫旅行6宣传了苏绣,也让各位妻子们穿上中国嫁衣,陈乔恩和艾伦结婚后也没有举办婚礼,也没有举办婚礼的打算。陈乔恩穿着红色中国嫁衣,有点泰国王族的感觉,非常正装表回温,品味板块正在重新排列虽然还没有很显著的趋势,但正装表确实正悄悄地回到许多表友搜寻的雷达中。随着人们休闲习惯和品味改变,许多以往被归类为运动表的款式如今也被认为可以搭配正式服装,穿搭变化也就比那些所谓正奇葩造型搏出位,就这么想红吗?春节接近尾声,想必大家和今天的我一样流下了返工两行泪。请挺住,新的一年别忘了还有会火陪伴你们。这个火热的中国年,想必大家回家见亲戚时都换上了新春的战袍但,各位的战袍再红,也不会比大最近火了一种颜色叫废土色,比你想象中高级,时尚圈都在穿其实一个人的穿搭什么时候会变得更时髦更有质感,这完全取决于一个人是否意识到了颜色选择和搭配的重要性,特别是崇尚极简穿搭的朋友,想要穿着有新意就必须要从颜色搭配入手。今年突然火了一种国表鉴赏之宝石花石英手表保养前面有提过,一直以来都是做机械手表的保养,很少做过石英手表保养。因为石英手表特性,所以石英手表保养需求极小,很多人戴几十年石英手表可能都没有保养过一次,也不会有走时不准确或不稳定的