如何把Java代码玩出花?JVM Sandbox入门教程与原理浅谈( 二 )


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

在沙箱的世界观中,任何一个Java方法的调用都可以分解为BEFORERETURNTHROWS三个环节,由此在三个环节上引申出对应环节的事件探测和流程控制机制 。
基于BEFORERETURNTHROWS三个环节事件分离,沙箱的模块可以完成很多类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包含了整个模块的生命周期回调函数 。