自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JAVA字節(jié)碼文件操作技巧

開(kāi)發(fā) 后端
本文將介紹與操作Java字節(jié)碼有關(guān)的基本知識(shí)和操作Java字節(jié)碼的方法及Demo,談到操作Java字節(jié)碼,不能不談到AOP,這里向大家做一下簡(jiǎn)單介紹。

你知道如何操作JAVA字節(jié)碼文件嗎,這里將介紹與操作Java字節(jié)碼有關(guān)的基本知識(shí)和操作Java字節(jié)碼的方法及Demo,首先我們來(lái)看一下AOP的概念,AOP是OOP的延續(xù),是AspectOrientedProgramming的縮寫(xiě),意思是面向方面編程。

如何操作JAVA字節(jié)碼文件

本文將介紹與操作Java字節(jié)碼有關(guān)的基本知識(shí)和操作Java字節(jié)碼的方法及Demo,談到操作Java字節(jié)碼,不能不談到AOP(AspectOrientedProgramming),下面來(lái)簡(jiǎn)單介紹一下:

AOP簡(jiǎn)介

AOP是OOP的延續(xù),是AspectOrientedProgramming的縮寫(xiě),意思是面向方面編程。AOP實(shí)際是GoF設(shè)計(jì)模式的延續(xù),設(shè)計(jì)模式孜孜不倦追求的是調(diào)用者和被調(diào)用者之間的解耦,AOP可以說(shuō)也是這種目標(biāo)的一種實(shí)現(xiàn)。

AOP的一個(gè)典型應(yīng)用就是J2EE。J2EE應(yīng)用系統(tǒng)只有部署在J2EE容器中才能運(yùn)行,那么為什么劃分為J2EE容器和J2EE應(yīng)用系統(tǒng)?通過(guò)對(duì)J2EE容器運(yùn)行機(jī)制的分析,可以發(fā)現(xiàn):實(shí)際上J2EE容器分離了一般應(yīng)用系統(tǒng)的一些通用功能,例如事務(wù)機(jī)制、安全機(jī)制以及對(duì)象池或線程池等性能優(yōu)化機(jī)制。

這些功能機(jī)制是每個(gè)應(yīng)用系統(tǒng)幾乎都需要的,因此可以從具體應(yīng)用系統(tǒng)中分離出來(lái),形成一個(gè)通用的框架平臺(tái),而且,這些功能機(jī)制的設(shè)計(jì)開(kāi)發(fā)有一定難度,同時(shí)運(yùn)行的穩(wěn)定性和快速性都非常重要,必須經(jīng)過(guò)長(zhǎng)時(shí)間調(diào)試和運(yùn)行經(jīng)驗(yàn)積累而成,因此,形成了專門(mén)的J2EE容器服務(wù)器產(chǎn)品,如TomcatJBoss。

簡(jiǎn)單了解AOP后,再來(lái)了解一下AOP底層技術(shù):

AOP(AspectOrientedProgramming)底層技術(shù)比較

AOP底層技術(shù)比較

從上面的圖表中分析可以看到,對(duì)于一般的操作Java字節(jié)碼要求(實(shí)際上是能夠滿足筆者100%的要求),綜合考慮功能,性能,可用性,易用性,使用Java字節(jié)碼框架來(lái)操作Java字節(jié)碼是最佳的選擇。

下面來(lái)了解一下都有哪些開(kāi)源操作JavaJava字節(jié)碼的框架:

Javassist;

cglib;

SERP;

Packagegnu.bytecode;

Cojen;

Jdec;

BCEL;

ObjectWebASM;

JClassLib;

TroveClassFileAPI;

Jiapi;

ClassfileReader&Writer;

JBET;

Retroweaver;

Jen;

Soot

這里重點(diǎn)介紹一下ASM,因?yàn)橄旅鎸⑹褂肁SM框架進(jìn)行Java字節(jié)碼修改。

ASM這個(gè)Java字節(jié)碼操控框架能被用來(lái)動(dòng)態(tài)生成類或者增強(qiáng)既有類的功能。ASM可以直接產(chǎn)生二進(jìn)制class文件,也可以在類被加載入Java虛擬機(jī)之前動(dòng)態(tài)改變類行為。Javaclass被存儲(chǔ)在嚴(yán)格格式定義的.class文件里,這些類文件擁有足夠的元數(shù)據(jù)來(lái)解析類中的所有元素:類名稱、方法、屬性以及Java字節(jié)碼(指令)。ASM從類文件中讀入信息后,能夠改變類行為,分析類信息,甚至能夠根據(jù)用戶要求生成新類。下圖對(duì)當(dāng)前接觸常用的操作Java字節(jié)碼框架進(jìn)行了一個(gè)比較:

操作Java字節(jié)碼框架比較 #p#

ASM的幾個(gè)特性:

1.JAVABased.

ASM是基于JAVA的,即用JAVA實(shí)現(xiàn)的。

2.Visitor模式.

對(duì)于ASM來(lái)說(shuō),Javaclass被描述為一棵樹(shù);使用“Visitor”模式遍歷整個(gè)二進(jìn)制結(jié)構(gòu)。

3.復(fù)雜性低.易學(xué)易用.

ASM提供了更為現(xiàn)代的編程模型,降低了操作Java字節(jié)碼的復(fù)雜性,使用事件驅(qū)動(dòng)的處理方式使得用戶只需要關(guān)注于對(duì)其編程有意義的部分,而不必了解Java類文件格式的所有細(xì)節(jié):ASM框架提供了默認(rèn)的“responsetaker”處理這一切。

4.較高的性能

對(duì)Java字節(jié)碼進(jìn)行操作的同時(shí)盡量減小的性能的損失(性能的損失是不可避免)。

這里來(lái)介紹一下ASM組成及順序圖:

ASM組成及順序圖


Corepackage提供了一個(gè)讀寫(xiě)、修改Javabytecode的API,并且為其它的package定義了依據(jù)。這個(gè)package對(duì)于生成Javabytecode、實(shí)現(xiàn)大多數(shù)的bytecode變換而言意義重大。

Treepackage提供了Javabytecode的內(nèi)存表示法。

Analysispackage提供了基本的數(shù)據(jù)流分析和類型檢查算法,它們將用于在treeoackage中存儲(chǔ)Java方法bytecode。

Commonspackage(包含在ASM2.0中)提供了一些常用的bytecode轉(zhuǎn)換和用于簡(jiǎn)化bytecode生成的適配器。

Utilpackage包含了一些幫助類和簡(jiǎn)單的bytecode驗(yàn)證器,它們將有助于開(kāi)發(fā)或者測(cè)試。

XMLpackage提供了一個(gè)用于在bytecode和XML之間進(jìn)行轉(zhuǎn)換的適配器,和一些允許使用XSLT定義bytecode轉(zhuǎn)換的兼容SAX的適配器。

順序圖:

ASM順序圖 

Demo

這里我們來(lái)實(shí)現(xiàn)這樣一個(gè)功能:在不能改變?cè)a功能的前提下,對(duì)于一個(gè)特定類的特定方法有沒(méi)有被測(cè)試過(guò),以HelloTaobao類中方法helloHeyun為例。

類HelloTaobao:

  1. publicclassHelloTaobao  
  2. {  
  3. publicvoidhelloHeyun()  
  4. {  
  5. System.out.println(“Hello,ThisisHeyun’sinvestigationaboutcodecoverage!”);  
  6. }  
  7. }  
  8.  

 主方法類:

  1. publicclassMain  
  2. {  
  3. publicstaticvoidmain(String[]args)  
  4. {  
  5. HelloTaobaoht=newHelloTaobao();  
  6. ht.heyunHeyun();  
  7. }  
  8. }  
  9.  

 到這里,我們運(yùn)行一下程序,會(huì)在Console輸出字符串:“Hello,ThisisHeyun’sinvestigationaboutcodecoverage!”。#p#

下面我們來(lái)操作一下Java字節(jié)碼文件HelloTaobao.class:

1.想操作Java字節(jié)碼的某一方法,需要繼承ASM中的ClassAdapter和MethodAdapter

2.定義類Generator來(lái)讀入Java字節(jié)碼文件HellTaobao,改造Java字節(jié)碼文件,生成改造后的同名Java字節(jié)碼文件HellTaobao,代碼如下:

  1. publicclassGenerator  
  2. {  
  3. publicstaticvoidmain(String[]args)throwsException  
  4. {  
  5. ClassReadercr=newClassReader(“HellTaobao”);  
  6.  
  7. ClassWritercw=newClassWriter(ClassWriter.COMPUTE_MAXS);  
  8.  
  9. ClassAdapterclassAdapter=newByteCodeClassHandler(cw);  
  10.  
  11. cr.accept(classAdapter,ClassReader.SKIP_DEBUG);  
  12.  
  13. byte[]data=cw.toByteArray();  
  14.  
  15. Filefile=newFile(“HellTaobao.class”);  
  16.  
  17. FileOutputStreamfout=newFileOutputStream(file);  
  18.  
  19. fout.write(data);  
  20.  
  21. fout.close();  
  22. }  
  23. }  
  24.  

 3.ByteCodeClassHandler(自定義)類繼承ClassAdapter(fromASM)

4.ByteCodeClassHandler類中重寫(xiě)visitMethod,這個(gè)方法里去判斷如果Java字節(jié)碼文件HelloTaobao.class包含方法helloHeyun就調(diào)用ByteCodeMethodHandler類

  1. publicclassByteCodeClassHandlerextendsClassAdapter  
  2. {  
  3. publicByteCodeClassHandler(ClassVisitorcv)  
  4. {  
  5. super(cv);  
  6. }  
  7. publicvoidvisit(intversion,intaccess,Stringname,Stringsignature,  
  8. StringsuperName,String[]interfaces)  
  9. {  
  10. super.visit(version,access,name,signature,superName,interfaces);  
  11. }  
  12. publicvoidvisitSource(Stringsource,Stringdebug)  
  13. {  
  14. super.visitSource(source,debug);  
  15.  
  16. }  
  17. publicvoidvisitEnd()  
  18. {  
  19. }  
  20.  
  21. @Override  
  22.  
  23. publicMethodVisitorvisitMethod(intaccess,Stringname,Stringdesc,  
  24.  
  25. Stringsignature,String[]exceptions)  
  26. {  
  27. MethodVisitormv=cv.visitMethod(access,name,desc,signature,  
  28.  
  29. exceptions);  
  30.  
  31. MethodVisitorwrappedMv=mv;  
  32.  
  33. if(mv!=null)  
  34.  
  35. {  
  36.  
  37. //對(duì)于”helloHeyun”方法進(jìn)行改造  
  38.  
  39. if(name.equals(“helloHeyun”))  
  40. {  
  41.  
  42. //使用自定義MethodVisitor,改寫(xiě)方法內(nèi)容  
  43.  
  44. wrappedMv=newByteCodeMethodHandler(mv);  
  45. }  
  46. }  
  47. returnwrappedMv;  
  48. }  
  49. }  
  50.  

 5.ByteCodeMethodHandler(自定義)繼承MethodAdapter(fromASM),這里來(lái)做改造想要調(diào)用的自定義方法,這里將調(diào)用類ControlByteCode(自定義)中的controlByteCodeByHeyun(自定義)方法

  1. publicclassByteCodeMethodHandlerextendsMethodAdapter  
  2. {  
  3. publicByteCodeMethodHandler(MethodVisitormv)  
  4. {  
  5. super(mv);  
  6. }  
  7. publicvoidvisitCode()  
  8. {  
  9. visitMethodInsn(Opcodes.INVOKESTATIC,“ControlByteCode”,  
  10.  
  11. “controlByteCodeByHeyun”,“()V”);  
  12. }  
  13. }  
  14.  

 6.ControlByteCode類的controlByteCodeByHeyun方法如下

  1. publicclassControlByteCode  
  2. {  
  3. publicstaticvoidcontrolByteCodeByHeyun()  
  4. {  
  5. System.out.println(“Thismethodhasalreadybeencovered.”);  
  6.  
  7. //TODOrealsecuritycheck  
  8. }  
  9. }  

7.這樣,當(dāng)運(yùn)行完Generator類中main方法后,會(huì)生成一個(gè)和原Java字節(jié)碼文件同名的文件(可以觀察出,會(huì)比以前的文件大,當(dāng)然也可以用MD5來(lái)確定是兩個(gè)不同文件)。

8.此時(shí)在運(yùn)行主方法類Main,會(huì)發(fā)現(xiàn)在Console打印如下:

  1. Hello,ThisisHeyun’sinvestigationaboutcodecoverage!  
  2.  
  3. Thismethodhasalreadybeencovered.  

9.由此,可以看出,在原功能沒(méi)有變化的前提下,通過(guò)改變Java字節(jié)碼文件,我們實(shí)現(xiàn)了CodeCoverage的雛形。實(shí)際上,很多CodeCoverage工具(如Cobertura)都是運(yùn)用此方法來(lái)實(shí)現(xiàn)Instrument(插裝)的。

【編輯推薦】

  1. IBM發(fā)布Java字節(jié)碼配置工具包BIPTK
  2. 深入學(xué)習(xí)JVM內(nèi)存設(shè)置原理和調(diào)優(yōu)
  3. JVM.dll裝載過(guò)程與源代碼分析
  4. 巧解使Eclipse崩潰的JVM terminated問(wèn)題
  5. 解決JVM Terminated.ExitCode=-1問(wèn)題行之有效的方法


 

責(zé)任編輯:佚名 來(lái)源: qa.taobao.com
相關(guān)推薦

2019-12-20 12:38:28

Java技術(shù)工具

2011-12-01 14:56:30

Java字節(jié)碼

2023-03-27 16:44:23

2021-12-09 22:36:30

Java 字節(jié)碼頁(yè)緩存

2023-11-30 16:05:17

2023-07-03 08:11:48

java字節(jié)碼字段

2019-10-30 08:45:21

JS代碼NodeJS

2009-12-16 11:04:51

Ruby操作文件權(quán)限

2022-03-30 10:10:17

字節(jié)碼棧空間

2009-12-21 11:19:50

WCF配置文件

2010-07-20 10:48:56

Perl文件操作

2009-12-10 15:41:35

PHP文件操作

2010-01-15 19:04:09

2010-03-22 12:40:48

Python代碼加密

2023-08-30 11:03:47

Java工具

2012-01-12 09:20:49

Java

2010-03-16 14:25:48

Linux操作系統(tǒng)

2018-04-04 15:05:17

虛擬機(jī)字節(jié)碼引擎

2013-11-15 17:23:50

Linux技巧文件管理

2009-12-16 10:49:42

Ruby操作二進(jìn)制文件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)