如何把Java代碼玩出花?JVM Sandbox入門教程與原理淺談( 二 )


// BEFOREtry {/** do something...*/// RETURNreturn;} catch (Throwable cause) {// THROWS}

在沙箱的世界觀中,任何一個Java方法的調用都可以分解為BEFORE、RETURNTHROWS三個環節,由此在三個環節上引申出對應環節的事件探測和流程控制機制 。
基于BEFORE、RETURNTHROWS三個環節事件分離,沙箱的模塊可以完成很多類AOP的操作 。
  1. 可以感知和改變方法調用的入參
  2. 可以感知和改變方法調用返回值和拋出的異常
  3. 可以改變方法執行的流程
    • 在方法體執行之前直接返回自定義結果對象,原有方法代碼將不會被執行
    • 在方法體返回之前重新構造新的結果對象,甚至可以改變為拋出異常
    • 在方法體拋出異常之后重新拋出新的異常,甚至可以改變為正常返回
一切都是事件驅動的,這一點你可能很迷糊,但是在下文的實戰環節中,可以幫助你理解 。
JVM Sandbox代碼實戰我將實戰章節提前到這里,目的是方便大家快速了解使用JVM SandBox開發是一件多么舒服的事情(相比于自己使用字節碼替換等工具) 。
使用版本:JVM-Sandbox 1.2.0
官方源碼:https://github.com/alibaba/jvm-sandbox
我們來實現一個小工具 , 在日常工作中,我們總會遇到一些巨大的Spring工程,里面有茫茫多的Bean和業務代碼,啟動一個工程可能需要5分鐘甚至更久,嚴重拖累開發效率 。
我們嘗試使用JVM Sandbox來開發一個工具,對應用的Spring Bean啟動耗時進行一次統計 。這樣能一目了然的發現工程啟動慢的主要原因,避免去盲人摸象的優化 。
最終效果如圖:
如何把Java代碼玩出花?JVM Sandbox入門教程與原理淺談

文章插圖
圖中統計了一個應用從啟動開始到所有SpringBean的啟動耗時 , 按照從高到低排序 , 我由于是demo應用 , Bean的耗時都偏低(也沒有太多業務Bean),但在實際應用中會有非常多幾秒甚至十幾秒才完成初始化的Bean , 可以進行針對性優化 。
在JVMSandBox中如何實現上面的工具?其實非常簡單 。
先貼上思路的整體流程:
如何把Java代碼玩出花?JVM Sandbox入門教程與原理淺談

文章插圖
首先新建Maven工程 , 在Maven依賴中引用JVM SandBox , 官方推薦獨立工程使用parent方式 。
<parent><groupId>com.alibaba.jvm.sandbox</groupId><artifactId>sandbox-module-starter</artifactId><version>1.2.0</version></parent>新建一個類作為一個JVM SandBox模塊 , 如下圖:
如何把Java代碼玩出花?JVM Sandbox入門教程與原理淺談

文章插圖
使用@Infomation聲明mode為AGENT模式 , 一共有兩種模式Agent和Attach 。
  • Agent:隨著JVM啟動一起啟動
  • Attach:在已經運行的JVM進程中 , 動態的插入
我們由于是監控JVM啟動數據,所以需要AGENT模式 。
其次,繼承com.alibaba.jvm.sandbox.api.Module和com.alibaba.jvm.sandbox.api.ModuleLifecycle 。
其中ModuleLifecycle包含了整個模塊的生命周期回調函數 。