ASM

本文介绍了ASM3.0,一个用于动态生成和修改类的Java字节码框架。ASM与APT、AspectJ、Javassist的关系分别进行了阐述,并通过示例解释了如何使用ASM进行类文件的修改,包括字节码的概念和访问者模式的应用。最后,文章提到了Javassist在修改字节码方面的便利性。
摘要由CSDN通过智能技术生成

今天介绍下ASM3.0,开始之前先思考几个问题:
1.ASM是什么?
2.ASM 跟传说中的AOP三剑客APT、aspectJ、Javassit有什么关系?
3.ASM是怎样修改class文件的?
带着问题开始今天的分享:

  1. ASM是什么?
    ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。说白了asm是直接通过字节码来修改class文件。
  2. ASM 跟传说中的AOP三剑客APT、aspectJ、Javassit有什么关系?
    分别解释下这几个名词
    APT:APT(Annotation Processing Tool)即注解处理器,是一种处理注解的工具,确切的说它是javac的一个工具,它用来在编译时扫描和处理注解。注解处理器以Java代码(或者编译过的字节码)作为输入,生成.java文件作为输出。简单来说就是在编译期,通过注解生成.java文件
    aspectJ:AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,所以它有一个专门的[编译器]用来生成遵守Java字节编码规范的Class文件。适合在某一个方法前后插入部分代码,处理某些逻辑:比如方法运行时间、插入动态权限检查等。问题会造成很多的冗余代码,产生很多代理类。简单来说就是在生成class时动态织入代码
    Javassit:Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba(千叶滋)所创建的。简单来说就是源码级别的api去修改字节码
    各种方式作用时机
  3. ASM是怎样修改class文件的?
    开始这个问题之前我们先学习几个东西。
    字节码:这里的字节码主要说的是Java字节码
    访问者模式:一个称为元素(Element),另一个称为访问者(Visitor)。元素有一个accept方法,该方法接收访问者作为参数;accept()方法调用访问者的visit()方法,并且将元素自身作为参数传递给访问者。由元素本身决定是否访问
    在ASM中元素(被访问者)ClassReader、MethodNode等等,访问者接口包含ClassVisitor、AnnotationVisitor、FieldVisitor、MethodVisitor
    下面我们先简单实现一个插桩操作
    有如下代码:
public class Main2Activity extends AppCompatActivity {
   
    private static int MESSAGE_KEY = 0x2019;
    @SuppressLint("HandlerLeak")
    private static Handler sHandler =new Handler() {
   
        @Override        
        public void handleMessage(Message msg) {
       
            if (msg.what ==MESSAGE_KEY) {
               
                if (msg.obj!=null) {
                    
                   Log.i("xmq", String.valueOf(msg.obj));                
                   }           
                 }      
          }   
 };       

@Override    
protected void onCreate(Bundle savedInstanceState) {
           
       super.onCreate(savedInstanceState);        
       setContentView(R.layout.activity_main);                      
       sendMessage(getClass().getSimpleName());
       }     

private void sendMessage(String string) {
   
        Message message = new Message();       
        message.what =MESSAGE_KEY;        
        sHandler.sendMessage(message);
}
}

我们要在sendMessage方法中添加一行代码变为下列

private void sendMessage(String string) {
   
    Message message = new Message();        
    message.what =MESSAGE_KEY;        
    message.obj = string;        
    sHandler.sendMessage(message
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值