返回

Annotations,简化代码插桩,不输ASM

Android

说到代码插桩,你可能会想到 AspectJ、Transfrom Api + ASM 等等。代码插桩的用处自不必说,可以做埋点、热修复、组件化路由等等。

然而,AspectJ 感觉不好用,ASM 比较复杂,需要自定义 gradle 插件。好在前段时间,我遇到了新的方法——AnnotationProcessor。

AnnotationProcessor 是一个注解处理库,可以用来处理注解,它提供了很多 hooks 来操作编译过程,我们可以利用这些 hooks 来修改字节码,从而实现代码插桩。

AnnotationProcessor 的使用很简单,只需要在项目中添加一个 annotationProcessor 的依赖,然后实现一个注解处理器,在注解处理器中实现代码插桩的逻辑即可。

dependencies {
  implementation 'com.google.auto.service:auto-service:1.0-rc7'
  annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7'
}
import com.google.auto.service.AutoService;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import java.util.Set;

@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_11)
@AutoService(Processor.class)
public class InsertTraceProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (Element element : roundEnv.getElementsAnnotatedWith(Trace.class)) {
            // do something
        }
        return true;
    }
}

AnnotationProcessor 的优势在于:

  • 简单易用,只需要实现一个注解处理器即可。
  • 灵活,可以根据自己的需要定制代码插桩的逻辑。
  • 高效,AnnotationProcessor 是在编译时运行的,不会影响程序的运行效率。

AnnotationProcessor 的缺点在于:

  • 只能修改字节码,不能修改源代码。
  • 需要一定的学习成本,需要了解 Java 注解处理器的相关知识。

总的来说,AnnotationProcessor 是一个非常实用的代码插桩工具,它简单易用,灵活高效,可以满足大多数代码插桩的需求。