提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|其它|编辑:郝浩|2010-09-25 11:48:00.000|阅读 709 次
概述:本文将介绍与操作Java字节码有关的基本知识和操作Java字节码的方法及Demo,谈到操作Java字节码,不能不谈到AOP,这里向大家做一下简单介绍。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
你知道如何操作JAVA字节码文件吗,这里将介绍与操作Java字节码有关的基本知识和操作Java字节码的方法及Demo,首先我们来看一下AOP的概念,AOP是OOP的延续,是AspectOrientedProgramming的缩写,意思是面向方面编程。
如何操作JAVA字节码文件
本文将介绍与操作Java字节码有关的基本知识和操作Java字节码的方法及Demo,谈到操作Java字节码,不能不谈到AOP(AspectOrientedProgramming),下面来简单介绍一下:
AOP简介
AOP是OOP的延续,是AspectOrientedProgramming的缩写,意思是面向方面编程。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。
AOP的一个典型应用就是J2EE。J2EE应用系统只有部署在J2EE容器中才能运行,那么为什么划分为J2EE容器和J2EE应用系统?通过对J2EE容器运行机制的分析,可以发现:实际上J2EE容器分离了一般应用系统的一些通用功能,例如事务机制、安全机制以及对象池或线程池等性能优化机制。
这些功能机制是每个应用系统几乎都需要的,因此可以从具体应用系统中分离出来,形成一个通用的框架平台,而且,这些功能机制的设计开发有一定难度,同时运行的稳定性和快速性都非常重要,必须经过长时间调试和运行经验积累而成,因此,形成了专门的J2EE容器服务器产品,如TomcatJBoss。
简单了解AOP后,再来了解一下AOP底层技术:
AOP(AspectOrientedProgramming)底层技术比较
从上面的图表中分析可以看到,对于一般的操作Java字节码要求(实际上是能够满足笔者100%的要求),综合考虑功能,性能,可用性,易用性,使用Java字节码框架来操作Java字节码是最佳的选择。
下面来了解一下都有哪些开源操作JavaJava字节码的框架:
Javassist;
cglib;
SERP;
Packagegnu.bytecode;
Cojen;
Jdec;
BCEL;
ObjectWebASM;
JClassLib;
TroveClassFileAPI;
Jiapi;
ClassfileReader&Writer;
JBET;
Retroweaver;
Jen;
Soot
这里重点介绍一下ASM,因为下面将使用ASM框架进行Java字节码修改。
ASM这个Java字节码操控框架能被用来动态生成类或者增强既有类的功能。ASM可以直接产生二进制class文件,也可以在类被加载入Java虚拟机之前动态改变类行为。Javaclass被存储在严格格式定义的.class文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及Java字节码(指令)。ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。下图对当前接触常用的操作Java字节码框架进行了一个比较:
ASM的几个特性:
1.JAVABased.
ASM是基于JAVA的,即用JAVA实现的。
2.Visitor模式.
对于ASM来说,Javaclass被描述为一棵树;使用“Visitor”模式遍历整个二进制结构。
3.复杂性低.易学易用.
ASM提供了更为现代的编程模型,降低了操作Java字节码的复杂性,使用事件驱动的处理方式使得用户只需要关注于对其编程有意义的部分,而不必了解Java类文件格式的所有细节:ASM框架提供了默认的“responsetaker”处理这一切。
4.较高的性能
对Java字节码进行操作的同时尽量减小的性能的损失(性能的损失是不可避免)。
这里来介绍一下ASM组成及顺序图:
Corepackage提供了一个读写、修改Javabytecode的API,并且为其它的package定义了依据。这个package对于生成Javabytecode、实现大多数的bytecode变换而言意义重大。
Treepackage提供了Javabytecode的内存表示法。
Analysispackage提供了基本的数据流分析和类型检查算法,它们将用于在treeoackage中存储Java方法bytecode。
Commonspackage(包含在ASM2.0中)提供了一些常用的bytecode转换和用于简化bytecode生成的适配器。
Utilpackage包含了一些帮助类和简单的bytecode验证器,它们将有助于开发或者测试。
XMLpackage提供了一个用于在bytecode和XML之间进行转换的适配器,和一些允许使用XSLT定义bytecode转换的兼容SAX的适配器。
顺序图:
Demo
这里我们来实现这样一个功能:在不能改变原代码功能的前提下,对于一个特定类的特定方法有没有被测试过,以HelloTaobao类中方法helloHeyun为例。
类HelloTaobao:
publicclassHelloTaobao
{
publicvoidhelloHeyun()
{
System.out.println(“Hello,ThisisHeyun’sinvestigationaboutcodecoverage!”);
}
}
主方法类:
publicclassMain
{
publicstaticvoidmain(String[]args)
{
HelloTaobaoht=newHelloTaobao();
ht.heyunHeyun();
}
}
到这里,我们运行一下程序,会在Console输出字符串:“Hello,ThisisHeyun’sinvestigationaboutcodecoverage!”。
下面我们来操作一下Java字节码文件HelloTaobao.class:
1.想操作Java字节码的某一方法,需要继承ASM中的ClassAdapter和MethodAdapter
2.定义类Generator来读入Java字节码文件HellTaobao,改造Java字节码文件,生成改造后的同名Java字节码文件HellTaobao,代码如下:
publicclassGenerator
{
publicstaticvoidmain(String[]args)throwsException
{
ClassReadercr=newClassReader(“HellTaobao”);
ClassWritercw=newClassWriter(ClassWriter.COMPUTE_MAXS);
ClassAdapterclassAdapter=newByteCodeClassHandler(cw);]
cr.accept(classAdapter,ClassReader.SKIP_DEBUG);
byte[]data=cw.toByteArray();
Filefile=newFile(“HellTaobao.class”);
FileOutputStreamfout=newFileOutputStream(file);
fout.write(data);
fout.close();
}
}
3.ByteCodeClassHandler(自定义)类继承ClassAdapter(fromASM)
4.ByteCodeClassHandler类中重写visitMethod,这个方法里去判断如果Java字节码文件HelloTaobao.class包含方法helloHeyun就调用ByteCodeMethodHandler类
publicclassByteCodeClassHandlerextendsClassAdapter
{
publicByteCodeClassHandler(ClassVisitorcv)
{
super(cv);
}
publicvoidvisit(intversion,intaccess,Stringname,Stringsignature,
StringsuperName,String[]interfaces)
{
super.visit(version,access,name,signature,superName,interfaces);
}
publicvoidvisitSource(Stringsource,Stringdebug)
{
super.visitSource(source,debug);
}
publicvoidvisitEnd()
{
}
@Override
publicMethodVisitorvisitMethod(intaccess,Stringname,Stringdesc,
publicMethodVisitorvisitMethod(intaccess,Stringname,Stringdesc,
{
MethodVisitormv=cv.visitMethod(access,name,desc,signature,
exceptions);
MethodVisitorwrappedMv=mv;
if(mv!=null)
{
//对于”helloHeyun”方法进行改造
if(name.equals(“helloHeyun”))
{
//使用自定义MethodVisitor,改写方法内容
wrappedMv=newByteCodeMethodHandler(mv);
}
}
returnwrappedMv;
}
}
5.ByteCodeMethodHandler(自定义)继承MethodAdapter(fromASM),这里来做改造想要调用的自定义方法,这里将调用类ControlByteCode(自定义)中的controlByteCodeByHeyun(自定义)方法
publicclassByteCodeMethodHandlerextendsMethodAdapter
{
publicByteCodeMethodHandler(MethodVisitormv)
{
super(mv);
}
publicvoidvisitCode()
{
visitMethodInsn(Opcodes.INVOKESTATIC,“ControlByteCode”,
“controlByteCodeByHeyun”,“()V”);
}
}
6.ControlByteCode类的controlByteCodeByHeyun方法如下
publicclassControlByteCode
{
publicstaticvoidcontrolByteCodeByHeyun()
{
System.out.println(“Thismethodhasalreadybeencovered.”);
//TODOrealsecuritycheck
}
}
7.这样,当运行完Generator类中main方法后,会生成一个和原Java字节码文件同名的文件(可以观察出,会比以前的文件大,当然也可以用MD5来确定是两个不同文件)。
8.此时在运行主方法类Main,会发现在Console打印如下:
Hello,ThisisHeyun’sinvestigationaboutcodecoverage!
Thismethodhasalreadybeencovered.
9.由此,可以看出,在原功能没有变化的前提下,通过改变Java字节码文件,我们实现了CodeCoverage的雏形。实际上,很多CodeCoverage工具(如Cobertura)都是运用此方法来实现Instrument(插装)的。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:网络转载面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢