// BEFOREtry {/** do something...*/// RETURNreturn;} catch (Throwable cause) {// THROWS}
在沙箱的世界观中,任何一个Java方法的调用都可以分解为一切都是事件驱动的,这一点你可能很迷糊,但是在下文的实战环节中,可以帮助你理解 。BEFORE
、RETURN
和THROWS
三个环节,由此在三个环节上引申出对应环节的事件探测和流程控制机制 。
基于BEFORE
、RETURN
和THROWS
三个环节事件分离,沙箱的模块可以完成很多类AOP的操作 。
- 可以感知和改变方法调用的入参
- 可以感知和改变方法调用返回值和抛出的异常
- 可以改变方法执行的流程
- 在方法体执行之前直接返回自定义结果对象,原有方法代码将不会被执行
- 在方法体返回之前重新构造新的结果对象,甚至可以改变为抛出异常
- 在方法体抛出异常之后重新抛出新的异常,甚至可以改变为正常返回
JVM Sandbox代码实战我将实战章节提前到这里,目的是方便大家快速了解使用JVM SandBox开发是一件多么舒服的事情(相比于自己使用字节码替换等工具) 。
使用版本:JVM-Sandbox 1.2.0
官方源码:https://github.com/alibaba/jvm-sandbox
我们来实现一个小工具 , 在日常工作中,我们总会遇到一些巨大的Spring工程,里面有茫茫多的Bean和业务代码,启动一个工程可能需要5分钟甚至更久,严重拖累开发效率 。
我们尝试使用JVM Sandbox来开发一个工具,对应用的Spring Bean启动耗时进行一次统计 。这样能一目了然的发现工程启动慢的主要原因,避免去盲人摸象的优化 。
最终效果如图:
文章插图
图中统计了一个应用从启动开始到所有SpringBean的启动耗时 , 按照从高到低排序 , 我由于是demo应用 , Bean的耗时都偏低(也没有太多业务Bean),但在实际应用中会有非常多几秒甚至十几秒才完成初始化的Bean , 可以进行针对性优化 。
在JVMSandBox中如何实现上面的工具?其实非常简单 。
先贴上思路的整体流程:
文章插图
首先新建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模块 , 如下图:文章插图
使用@Infomation声明mode为AGENT模式 , 一共有两种模式Agent和Attach 。
- Agent:随着JVM启动一起启动
- Attach:在已经运行的JVM进程中 , 动态的插入
其次,继承com.alibaba.jvm.sandbox.api.Module和com.alibaba.jvm.sandbox.api.ModuleLifecycle 。
其中ModuleLifecycle包含了整个模块的生命周期回调函数 。
- onLoad:模块加载,模块开始加载之前调用!模块加载是模块生命周期的开始,在模块生命中期中有且只会调用一次 。这里抛出异常将会是阻止模块被加载的唯一方式,如果模块判定加载失败,将会释放掉所有预申请的资源,模块也不会被沙箱所感知
- onUnload:模块卸载,模块开始卸载之前调用!模块卸载是模块生命周期的结束,在模块生命中期中有且只会调用一次 。这里抛出异常将会是阻止模块被卸载的唯一方式,如果模块判定卸载失败,将不会造成任何资源的提前关闭与释放,模块将能继续正常工作
- onActive:模块被激活后,模块所增强的类将会被激活,所有com.alibaba.jvm.sandbox.api.listener.EventListener将开始收到对应的事件
- onFrozen:模块被冻结后,模块所持有的所有com.alibaba.jvm.sandbox.api.listener.EventListener将被静默,无法收到对应的事件 。需要注意的是,模块冻结后虽然不再收到相关事件,但沙箱给对应类织入的增强代码仍然还在 。
- loadCompleted:模块加载完成,模块完成加载后调用!模块完成加载是在模块完成所有资源加载、分配之后的回调,在模块生命中期中有且只会调用一次 。这里抛出异常不会影响模块被加载成功的结果 。模块加载完成之后,所有的基于模块的操作都可以在这个回调中进行
推荐阅读
- 如何理解Java中眼花缭乱的各种并发锁?
- 如何删除微信零钱明细(零钱明细账能一次全部删除吗)
- QQ如何手动升级(电脑上qq怎么升级)
- qq安全如何升级(qq安全中心不能直接改密码了)
- 如何更新电脑QQ版本(电脑qq关闭自动更新)
- 手把手教你使用netty搭建一个DNS tcp服务器
- 什么是 X.509 证书以及它是如何工作的?
- 新qq如何快速升级qq怎么快速升级(在qq怎么快速升级等级)
- 英雄联盟怎么玩好(新人如何玩好英雄联盟)
- 如何才能玩好英雄联盟(怎么样才能玩英雄联盟最好)