安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

基于Javassist实现Java动态代理

8月16日 观潮阁投稿
  阅读完本文你能get到的知识点什么是JavassistJDK动态代理使用Javassist实现和JDK一样的效果什么是Javassist
  很多同学估计会对这个词有点陌生,但随着你关注的博主越来越多,知道的也越来越多,马上这篇文章就带你走进Javassist的世界
  Javassist和ASM一样是操作字节码的框架,Javassist诞生于1999年,多少有点年头
  使用Javassist可以在运行时定义一个新类,可以在JVM加载类文件时修改类文件
  而且Javassist提供不同类型的API:源码级别和字节码级别
  本文使用源码级别的API,所以你甚至可以在不懂字节码的前提下使用它,入手相对简单
  但在性能上略逊于ASMJDK动态代理
  话不多说,先来回顾一下我们平时是怎么使用JDK动态代理的Proxy
  JDK提供一个类Proxy用于生成代理类
  调用类方法newProxyInstance,传入的参数ClassLoaderloader:定义代理类的类加载器C?〔〕interfaces:代理类需要实现的所有接口InvocationHandlerh:调用处理程序,方法调用都会分派到这里
  InvocationHandler
  InvocationHandler是一个接口类,定义了调用方法Objectproxy:生成的代理对象Methodmethod:接口方法实例Object〔〕args:方法调用中传递的参数值
  如何调用
  调用Proxy。newProxyInstance生成代理对象,传入参数接口InvocationHandler实现类的对象处理代理的逻辑
  代码设计
  在动手写代码之前,我们先花几分钟在脑海中设想一下我们需要生成的代理类是什么样子的?
  这里先揭晓了
  假设我们定义了一个接口类LoginService定义的接口类
  那么我们需要生成一个大概是这样的代理类首先必须得实现了定义的接口LoginService接口的所有方法实现都调用都代理到InvocationHandler中
  几个重要的类
  从上面生成的代理类入手,我们生成的类
  继承了父类MObject
  实现了需要代理的接口LoginService
  生成了类成员变量LoginService0,这个对应接口的定义的方法
  实现了需要代理的接口方法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方法设置变量的修饰符为staticprivate
  因为这里还要设置变量的值
  调用getFieldInitCode生成初始化代码
  为了获取Method对象,这里生成了反射的代码去获取
  实例:Class。forName(类名)。getMethod(方法名,C?。。。方法的参数类型);
  生成了类成员变量之后,接下来该到实现接口的方法了实现接口方法
  这里需要实现接口的方法
  可以通过CtNewMethod。copy方法去拷贝需要实现的方法,不要直接使用原来的CtMethod,防止污染
  拿到新的CtMethod,我们需要设置它的方法体、设置修饰符为public
  重点来看看怎么生成方法体代码
  这里根据方法返回的类型调用不同的方法void:没有返回值的调用getMethodBodyCodeByVoid基本数据类型:调用getMethodBodyCodeByPrimitive其它类型:调用getMethodBodyCode
  那按顺序来看,不需要返回值的
  那我们需要生成的代码是长这样的
  super。h。invoke(this,对应的类成员变量,newObject〔〕{方法参数});
  这个有个语法需要知道:0代表这方法的第一个参数,懂字节码的应该知道非构造方法的第一个入参是一个隐式的this,指向对象本身
  newObject〔〕{}里面就可以用1112代表着方法的参数了
  返回值是基本数据类型的,需要调用调用包装类型对应的拆箱方法如
  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。cnpost7168030376080703495
投诉 评论 转载

不出意外,2022世界杯冠军在这5支球队产生,曾合计获得142022年的卡塔尔世界杯是十分精彩的世界杯,充满无限奇迹和无限的可能,就在昨日,沙特阿拉伯爆冷21逆转击败冠军热门球队阿根廷队,让大牌球星梅西颜面无光,法国则是以41的大比分击……新零售2022调料精酿预制菜【潮汐商业评论原创】圣诞节临近,刚刚下班的Emily想着好久没有与闺蜜见面了,于是相约着过平安夜。她顺手就打开盒马APP下单了适合女生的微醺精酿,同时发现零售平台上……帮助糖友安稳过国庆的10个小方法,快点收藏原创郭玉佩糖友苑2022100212:01:26发表于河南手机阅读每逢假期,生活节奏稍有改变,血糖就会波动,做到以下10条,糖友可以放心安全度假啦!1。主食每……基于Javassist实现Java动态代理阅读完本文你能get到的知识点什么是JavassistJDK动态代理使用Javassist实现和JDK一样的效果什么是Javassist很多同学估计会对这个词有点陌生,但……2米26姚明的巨人体型大本在他面前像后卫,大腿比普通人腰还粗众所周知,姚明作为我们国家第一位、也是唯一一位NBA的状元秀当年他能够成功打进NBA,并且取得不俗的成绩,他惊人的身高无疑是重要原因。在普通人视角里,身高1米9已经能够称……湖人公布新赛季球衣,勒布朗和浓眉却被这个C位新人抢了风头可能是为了一扫球队在休赛期里一直碌碌无为的阴霾,洛杉矶湖人队在近日尬发了一款202223赛季复古经典版本的球衣。但讲真,在我第一眼看到这款球衣时的感觉,简直就可以用寡淡这……苹果分销商妥协了,128GB版iPhone跌至3799元,等声明:原创不易,禁止搬运,违者必究!苹果手机的保值度还是非常高的,甚至在苹果的官网上,苹果的产品很多都还维持原价。而手机市场上,我们买到降价的苹果手机,其实是分销商降价了……CES新车FF91实车亮相,中大型SUV,造型动感,期待量产在2023CES展览会现场,我们看到了FaradayFuture旗下FF91实车,FF91车型定位中大型SUV,那么车子的静态表现如何?车子的动力参数表现如何?车子什么时候能上……6换1,篮网交易夏普组四巨头?美媒伍德将大幅提升篮网内线实力大家好,我们今天来聊聊美媒报道的一笔交易方案:6换1,篮网交易夏普组四巨头?美媒:伍德将大幅提升篮网内线实力。火箭队在上一场比赛中输给了独行侠队,虽然伍德砍下了20分,但……人类起源于地球而非外太空,为何主流科学界坚信这点?关于人类起源,有很多种观点,不过主流科学界只认同一种观点:人类起源于地球。这种观点并不是胡乱猜想,而是有科学依据的。虽然我们的想象力很丰富,很多科幻小说和电影里都有人类并……夏天上火太痛苦,这六种食物火上浇油,易引起口腔溃疡巴黎8月5日(胡桢)根据canalnews报导,夏季昼长夜短,食欲减退,身体消耗大,对人体来说,会导致虚火旺盛,身体出现炎症,产生喉咙不适、长痘、口腔溃疡等症状,这样一来,内外……骗了我们多年的穿帮镜头冲锋枪我忍了嘟嘴卖萌忍不了土生金爱搞笑影视剧中经常避免不了有一些穿帮镜头,虽然不会影响整个电视剧,但是有时候却能观众把乐坏了,所以让我们一起来互相调侃吧!骗了我们多年的穿帮镜头,冲锋枪我忍了,嘟嘴卖萌这个忍不了……
企业年度工作总结1500字实用的幸福读后感作文500字集合六篇2022敢转争心得体会校园活动通讯稿范文企业员工思想汇报范文关于学校食堂的工作总结5篇入党志愿书范文2022年公司六一儿童节放假通知2021团委工作自查报告拔河比赛策划书方案幼儿园家委会活动工作计划初中教务处工作计划范文3篇

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利