JavaShuo
欄目
標籤
java asm 框架 淺析
時間 2019-11-07
標籤
java
asm
框架
淺析
欄目
Java
简体版
原文
原文鏈接
什麼是asm呢?asm是assembly的縮寫,是彙編的稱號,對於java而言,asm就是字節碼級別的編程。
而這裏說到的asm是指objectweb asm,一種.class的代碼生成器的開源項目.
ASM是一套java字節碼生成架構,它能夠動態生成二進制格式的stub類或其它代理類,
或者在類被java虛擬機裝入內存以前,動態修改類。
如今挺多流行的框架都使用到了asm.因此從aop追溯來到了這。
1.什麼是ObjectWeb ASM
ObjectWeb ASM是輕量級的Java字節碼處理框架。它能夠動態生成二進制格式的stub類或其餘代理類,或者在類被JAVA虛擬機裝入內存以前,動態修改類。
ASM 提供了與 BCEL和SERP類似的功能,只有22K的大小,比起350K的BCEL和150K的SERP來講,是至關小巧的,而且它有更高的執行效率,
是BCEL 的7倍,SERP的11倍以上。
在我看來,ObjectWeb ASM具備以下幾個很是誘人的特色
* 小巧、高效
* 源代碼實現很是簡潔而又優雅,簡直就是Gof的《設計模式》很是棒的註解
* 字節碼級的控制,可以更高效地實現字節碼的控制
ObjectWeb ASM有2組接口:
* 基於事件驅動的接口,相似於xml的SAX接口,visitor模式,在訪問到類定義某個部分的時候進行回調,實現上比tree接口高效,佔用內存更小
* 基於tree的接口,相似於xml的DOM接口,將類定義解析成tree
這裏咱們將使用ObjectWeb ASM的事件驅動接口
2. 目標
咱們將對已有的字節碼進行加強,收集進入方法和退出方法的信息,這裏主要解決Method Monitor的字節碼加強部分,
不對收集後的數據處理作更深刻地研究,出於演示的目的,咱們定義了以下的收集方法的訪問信息處理,
在實際應用中,咱們可能會使用更好的格式收集更多的數據、使用異步處理提升性能、使用批量處理提升處理能力、使用友好的UI顯示信息等等,
此處不對這部分進行探討
1. package blackstar.methodmonitor.instrutment.monitor;
2. public class MonitorUtil
3. {
4. public final static String CLASS_NAME = MonitorUtil.class.getName()
5. .replaceAll("\\.", "/");
6. public final static String ENTRY_METHOD = "entryMethod";
7. public final static String EXIT_METHOD = "exitMethod";
8. public final static String METHOD = "(Ljava/lang/String;Ljava/lang/String;)V";
9.
10. public static void entryMethod(String className, String methodName)
11. {
12. System.out.println("entry : " + className + "." + methodName);
13. }
14.
15. public static void exitMethod(String className, String methodName)
16. {
17. System.out.println("exit : " + className + "." + methodName);
18. }
19. }
3. 從字節碼開始
實際上,對於被監控制的代碼,咱們所須要實現的功能以下,紅色部分的代碼是咱們須要在動態期插到字節碼中間的
public xxx method(…)
{
try
{
methodEntry(…)
methodCode
}
finally
{
methodExit(…)
}
}
這個問題看起來簡單,實際則沒有那麼容易,由於在JVM的字節碼設計中,字節碼並不直接支持finally語句,而是使用try…catch來模擬的,咱們先來看一個例子
Java代碼
1. package blackstar.methodmonitor.instrutment.test;
2.
3. public class Test
4. {
5. public void sayHello() throws Exception
6. {
7. try
8. {
9. System.out.println("hi");
10. } catch (Exception e)
11. {
12. System.out.println("exception");
13. return;
14. } finally
15. {
16. System.out.println("finally");
17. }
18. }
19. }
咱們看看字節碼是如何處理finally語句的
首先看看異常表,異常是在JVM級別上直接支持的,下面異常表的意思是,在執行0-8語句的時候,若是有異常java.lang.Exception拋出,則進入第11語句,
在執行0-20語句的時候,有任何異常拋出,都進入29語句。實際上JVM是這樣實現finally語句的:
* 在任何return語句以前,都會增長finally語句中的字節碼
* 定義一個捕獲全部異常的語句,增長finally語句中的字節碼,若是finally中沒有return語句,則會將異常再次拋出去(處理方法以拋出異常的方式結束)
Exceptions:
[0-8): 11 - java.lang.Exception
[0-20): 29
咱們再看看字節碼具體是如何作的
0 getstatic java.lang.System.out
3 ldc "hi" (java.lang.String)
5 invokevirtual println
8 goto 40
// System.out.println("hi");,執行完以後執行返回(goto 40)
11 astore_1
12 getstatic java.lang.System.out
15 ldc "exception" (java.lang.String)
17 invokevirtual println
// System.out.println("exception");
20 getstatic java.lang.System.out
23 ldc "finally" (java.lang.String)
25 invokevirtual println
// return語句以前插入finally部分字節碼
// System.out.println("finally");
28 return
29 astore_2
30 getstatic java.lang.System.out
33 ldc "finally" (java.lang.String)
35 invokevirtual println
38 aload_2
39 athrow
//當在執行0-29語句中,若是有異常拋出,則執行這段finally語句
//此處的astore_2(將棧頂值——即exception的地址——設給第2個local變量)和aload_2(將第2個local變量的值入棧)這兩個字節碼實際是沒必要要的,
//但須要注意的是,若是這2段代碼去掉的話,要考慮增大操做棧(max stack)以容納這個exception地址
//System.out.println("finally");
40 getstatic java.lang.System.out
43 ldc "finally" (java.lang.String)
45 invokevirtual println
// return語句以前插入finally部分字節碼
// System.out.println("finally");
48 return
實際上,咱們須要作的就是
* 在方法進入時插入方法進入代碼(須要注意,對於構造函數不容許作這種處理,構造函數第一步必須調用父類的構造函數。
* 在每一個return操做(包括return、ireturn、freturn等)以前,插入方法退出代碼
* 定義一個捕獲全部異常的處理,在處理中,插入方法退出代碼(即方法以拋異常的方式終止執行)
4. 實現
咱們看看使用ObjectWeb ASM如何實現咱們上面描述的功能
1)ObjectWeb ASM的字節碼修改
1. ClassReader cr = new ClassReader(byteArray); //使用字節碼構監一個reader
2. ClassWriter cw = new ClassWriter(cr, 0);//writer將基於已有的字節碼進行修改
3. MonitorClassVisitor ca = new MonitorClassVisitor(cw);//修改處理回調類
4. cr.accept(ca, 0);
相關文章
1.
Java字節碼框架ASM
2.
Java中ASM框架詳解
3.
Java 集合框架淺析
4.
【Java】淺析SSH框架
5.
Java——集合框架(淺析)
6.
淺析IoC框架
7.
Backbone框架淺析
8.
LitePal框架淺析
9.
淺析Dubbo框架
10.
Java字節碼修改框架ASM
更多相關文章...
•
Java Spring框架是什麼?它有哪些好處?
-
Spring教程
•
SQLite - Java
-
SQLite教程
•
Java 8 Stream 教程
•
互聯網組織的未來:剖析GitHub員工的任性之源
相關標籤/搜索
java框架
淺析
asm
框架
JAVA集合框架
java通訊框架
J2EE淺析
源碼淺析
淺淺
Java
MyBatis教程
Hibernate教程
Spring教程
java
架構
Java 8
0
分享到微博
分享到微信
分享到QQ
每日一句
每一个你不满意的现在,都有一个你没有努力的曾经。
最新文章
1.
融合阿里雲,牛客助您找到心儀好工作
2.
解決jdbc(jdbctemplate)在測試類時不報錯在TomCatb部署後報錯
3.
解決PyCharm GoLand IntelliJ 等 JetBrains 系列 IDE無法輸入中文
4.
vue+ant design中關於圖片請求不顯示的問題。
5.
insufficient memory && Native memory allocation (malloc) failed
6.
解決IDEA用Maven創建的Web工程不能創建Java Class文件的問題
7.
[已解決] Error: Cannot download ‘https://start.spring.io/starter.zip?
8.
在idea讓java文件夾正常使用
9.
Eclipse啓動提示「subversive connector discovery」
10.
帥某-技巧-快速轉帖博主文章(article_content)
本站公眾號
歡迎關注本站公眾號,獲取更多信息
相關文章
1.
Java字節碼框架ASM
2.
Java中ASM框架詳解
3.
Java 集合框架淺析
4.
【Java】淺析SSH框架
5.
Java——集合框架(淺析)
6.
淺析IoC框架
7.
Backbone框架淺析
8.
LitePal框架淺析
9.
淺析Dubbo框架
10.
Java字節碼修改框架ASM
>>更多相關文章<<