一、alibaba/jvm-sandbox 概述
alibaba/jvm-sandbox 是 JVM 沙箱容器,一种 JVM 的非侵入式运行期 AOP 解决方案。沙箱容器提供
- 动态增强类你所指定的类,获取你想要的参数和行信息甚至改变方法执行
- 动态可插拔容器框架
在其能力至上构建的上层应用有:
- chaosblade-io/chaosblade
- 其chaosblade-io/chaosblade-exec-jvm 是一个基于 jvm-sandbox 的 chaosblade 执行器,用于通过增强类在 Java 应用程序上进行混沌实验。
- alibaba/jvm-sandbox-repeater
- 基于 JVM-Sandbox 的录制/回放通用解决方案
二、实时无侵入 AOP 框架方案对比
在常见的 AOP 框架实现方案中,有静态编织和动态编织两种。
-
静态编织:静态编织发生在字节码生成时根据一定框架的规则提前将 AOP 字节码插入到目标类和方法中,实现 AOP;
-
动态编织:动态编织则允许在 JVM 运行过程中完成指定方法的 AOP 字节码增强.常见的动态编织方案大多采用重命名原有方法,再新建一个同签名的方法来做代理的工作模式来完成 AOP 的功能(常见的实现方案如 CgLib),但这种方式存在一些应用边界:
- 侵入性:对被代理的目标类需要进行侵入式改造。比如:在 Spring 中必须是托管于 Spring 容器中的 Bean
- 固化性:目标代理方法在启动之后即固化,无法重新对一个已有方法进行 AOP 增强
要解决无侵入
的特性需要 AOP 框架具备 在运行时完成目标方法的增强和替换。在 JDK 的规范中运行期重定义一个类必须准循以下原则
- 不允许新增、修改和删除成员变量
- 不允许新增和删除方法
- 不允许修改方法签名
JVM-SANDBOX 属于基于 Instrumentation 的动态编织类的 AOP 框架,通过精心构造了字节码增强逻辑,使得沙箱的模块能在不违反 JDK 约束情况下实现对目标应用方法的无侵入
运行时 AOP 拦截。
三、基于事件的行为注入和流控
在沙箱的世界观中,任何一个 Java 方法的调用都可以分解为BEFORE
、RETURN
和THROWS
三个环节,由此在三个环节上引申出对应环节的事件探测和流程控制机制。
// BEFORE
try {
/*
* do something...
*/
// RETURN
return;
} catch (Throwable cause) {
// THROWS
}
复制代码
基于BEFORE
、RETURN
和THROWS
三个环节事件分离,沙箱的模块可以完成很多类 AOP 的操作。
-
可以感知和改变方法调用的入参
-
可以感知和改变方法调用返回值和抛出的异常
-
可以改变方法执行的流程
- 在方法体执行之前直接返回自定义结果对象,原有方法代码将不会被执行
- 在方法体返回之前重新构造新的结果对象,甚至可以改变为抛出异常
- 在方法体抛出异常之后重新抛出新的异常,甚至可以改变为正常返回
四、最后说一句
我是石页兄,如果这篇文章对您有帮助,或者有所启发的话,欢迎关注笔者的微信公众号【 架构染色 】进行交流和学习。您的支持是我坚持写作最大的动力。
作者:Applehope
原文链接:https://juejin.cn/post/7182790460640624696