java agent技术原理及简单实现

本文探讨了在不修改原有代码的情况下,实现方法mock、暂停和异常模拟的技术思路,包括代理模式(CGLIB和AspectJ)及其局限性。随后介绍了Java Agent技术,它允许在类加载前或运行时修改字节码,以实现无侵入的MOCK功能。Java Agent通过Instrumentation API在启动时或运行时加载,并借助JVMTI和ClassFileTransformer实现字节码修改。文章详细阐述了Java Agent的加载、启动时修改和运行时修改的原理,以及何时进行运行时字节码替换。
摘要由CSDN通过智能技术生成

1、引子

在某天与QA同学进行沟通时,发现QA同学有针对某个方法调用时,有让该方法停止一段时间的需求,我对这部分的功能实现非常好奇,因此决定对原理进行一些深入的了解,力争找到一种使用者尽可能少的对原有代码进行修改的方式,以达到对应的MOCK要求。

整体的感知程度可以分为三个级别:

硬编码
增加配置
无需任何修改
2、思路
在对方法进行mock,暂停以及异常模拟,在不知道其原理的情况下,进行猜想,思考其具体的实现原理,整体来说,最简单的实现模型无外乎两种:

2.1 朴素思路
假设存在如下的函数

publicObject targetMethod(){

System.out.println(“运行”);

}

若想要在函数执行后暂停一段时间、返回特定mock值或抛出特定异常,那么可以考虑修改对应的函数内容:

public Object targetMethod(){
//在此处加入Sleep return 或 throw逻辑
System.out.println(“运行”);
}
或使用类似代理的方法把对应的函数进行代理:

public Object proxy(){
//执行Sleep return 或 throw逻辑
return targetMethod();
}
public Object targetMethod(){
System.out.println(“运行”);
}
2.2 略成熟思路
在朴素思路的基础上,我们可以看出,实现类似的暂停、mock和异常功能整体实现方案无外乎两种:

代理模式
深入修改内部函数
在这两种思路的基础上,我们从代理模式开始考虑(主要是代理使用的比较多,更熟悉)

2.2.1 动态代理
说起代理,最常想到的两个词语就是静态代理和动态代理,二者却别不进行详述,对于静态代理模式由于需要大量硬编码,所以完全可以不用考虑。

针对动态代理来看,开始考虑最具代表性的CGLIB进行调研。

下面的代码为一个典型的使用CGLIB进行动态代理的样例(代理的函数为PersonService.setPerson):

public class CGlibDynamicProxy implements MethodInterceptor { public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println(“执行前…”); Object object = methodProxy.invokeSuper(o, objects); System.out.println(“执行后…”); return object; } static class PersonService { public PersonService() { System.out.println(“PersonService构造”); } public void setPerson() { System.out.println(“PersonService:setPerson”); } } public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(PersonService.class); enhancer.setCallback(new CGlibDynamicProxy()); PersonService proxy= (PersonService) enhancer.create(); proxy.setPerson(); }}
从上面代码可以看出,对于CGLIB的动态代理而言,需要在原有代码中进行硬编码,且需要在对象初始化的时候,使用特定的方式进行初始化。因此若使用CGLIB完成MOCK,需要对应代码的的感知程度最高,达到了硬编码的程度。

2.2.2 AspectJ
由于使用代理方式无法在不对代码进行修改的情况下完成MOCK,因此我们抛弃代理方式࿰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值