Arthas源码分析(二)——类增强

本文详细分析了Arthas的类增强过程,从SpyInterceptors的内部类结构到SpyAPI的静态方法,再到SpyImpl的实现和AdviceListenerManager的监听器管理。重点讲解了Enhancer如何在方法调用时进行增强,并注册监听器,以及TransformerManager如何统一管理ClassFileTransformer。整个流程展示了Arthas如何实现对目标类和方法的动态拦截和增强。
摘要由CSDN通过智能技术生成

前文忘了提到,源码版本3.5.1。 如果有任何纰漏欢迎指出。

目录

1 SpyInterceptors

2 SpyAPI

3 SpyImpl

4 AdviceListenerManager

5 Enhancer

6 TransformerManager


1 SpyInterceptors

        Arthas中所有的切面拦截都是在SpyInterceptors的内部类中,9个内部类可以分为三类,分别是拦截目标方法的SpyInterceptor内部类、拦截目标方法内部子调用(包括JDK的子调用)的SpyTraceInterceptor内部类、拦截目标方法内部子调用(不包含所有JDK的子调用)的SpyTraceExcludeJDKInterceptor内部类,类图如下所示。

SpyInterceptors

        所有内部类当中有且只有一个静态方法,每个静态方法都会调用SpyAPI这个类中对应的静态方法。所以这九个类中的九个静态方法,是用来增强到目标方法切面的,而每个切面具体执行的代码还要看SpyAPI里的代码。 

2 SpyAPI

        SpyAPI的类图如下图所示。

SpyAPI的类图

        SpyAPI当中的6个“at…”静态方法都调用了实例spyInstance中对应的方法。spyInstance的静态类型是抽象类AbstractSpy,抽象类AbstractSpy当中有六个抽象方法。当SpyAPI被加载时,它的静态语句会将spyInstance设置为类NopSpy的实例,其中这NopSpy继承自AbstractSpy并且实现的每个方法都是空操作。

        当加载类Enhancer的时候会有一条静态语句来初始化SpyAPI,如下。代码当中的SpyImpl也是继承自AbstractSpy,经此,切面拦截时将调用类SpyImpl中对应的方法,下一节接着SpyImpl看。

private static SpyImpl spyImpl = new SpyImpl();
static {
    SpyAPI.setSpy(spyImpl);
}

        另外,需要说明的是,为何SpyAPI的包名是以java开头,并且要在ArthasBootstrap单例初始化的时候将其附加到引导类加载器,就是为了能够让所有的Class都能够让SpyAPI中的静态方法能够被任意类调用。如果SpyAPI是由ArthasClassLoader加载,那么其父加载器ExtClassLoader加载的类就无法调用SpyAPI中的方法,最直接的影响就是AppClassLoader加载的类都无法调用SpyAPI。 

3 SpyImpl

        SpyImpl的类图如下,没有多少看头。

SpyImpl的类图

         六个“at…”方法中每个方法的逻辑都是一样的,以atEnter为例代码如下。


@Override
public void atEnter(Class<?> clazz,
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值