深入了解JVM字节码增强技术
这篇文章主要介绍了深入了解JVM字节码增强技术,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
JVM——字节码增强技术简介
Java字节码增强指的是在Java字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修改。Java字节码增强主要是为了减少冗余代码,提高性能等。
实现字节码增强的主要步骤为:
1、修改字节码
在内存中获取到原来的字节码,然后通过一些工具(如ASM,Javaasist)来修改它的byte[]数组,得到一个新的byte数组。
2、使修改后的字节码生效
有两种方法:
1)自定义ClassLoader来加载修改后的字节码;
2)替换掉原来的字节码:在JVM加载用户的Class时,拦截,返回修改后的字节码;或者在运行时,使用Instrumentation.redefineClasses方法来替换掉原来的字节码;
3.两种实现机制:
(1)通过创建原始类的一个子类(动态创建的类继承原来的类)。子类名以原始类名为前缀,以避免重名。SpringAOP使用的就是这种
(2)直接修改原始类的字节码。类的跟踪过程中使用
4.实现字节码增强要执行两个步骤:
(1)在内存中获取到原始的字节码,然后通过一些开源的API来修改它的byte[]数组,得到一个新的byte[]数组。
(2)将新的byte[]数组加载到PermGen区(即加载新的byte[]数组或替换原始类的字节码)。
接口BCInterface
publicinterfaceBCInterface{ voidenhancement(); }
实现类BCEnhancement.java
publicclassBCEnhancementimplementsBCInterface{ publicvoidenhancement(){ System.out.println("helloenhancement"); } }
LogProxy.java
importjava.lang.reflect.InvocationHandler; importjava.lang.reflect.Method; importjava.lang.reflect.Proxy; publicclassLogProxyimplementsInvocationHandler{ privateObjectobject; publicObjectgetProxyObject(Objecto){ object=o; try{ returnProxy.newProxyInstance(this.getClass().getClassLoader(),o.getClass().getInterfaces(),this); }catch(IllegalArgumentExceptione){ thrownewRuntimeException(e); } } publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{ System.out.println("beforeinvoke..."); Objectresult=method.invoke(object,args); System.out.println("afterinvoke..."); returnresult; } }
测试类Test.java
publicclassTest{ publicstaticvoidmain(String[]args){ LogProxylogProxy=newLogProxy(); System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles","true"); BCInterfacebyteCodeEn=(BCInterface)logProxy.getProxyObject(newBCEnhancement()); byteCodeEn.enhancement(); } }
输出:
beforeinvoke... helloenhancement afterinvoke...
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。