不写废话,帮助你快速理解应对面试
目录
什么是编译插桩
插桩的应用场景
插桩的工具
什么是编译插桩
用通俗的话来讲,插桩就是将一段代码通过某种策略插入到另一段代码,或替换另一段代码。
这里的代码可以分为源码和字节码,而我们所说的插桩一般指字节码插桩。
实际上,我们项目中经常用到的Dagger、ButterKnife甚至是Kotlin语言,它们都用到了编译插桩的技术。
下面是Android项目中.java文件的编译过程:
.java文件编译过程
从上图过程中,我们可以看出可以从2个地方进行改造:
- 在.java文件编译成.class文件时,APT、AndroidAnnotation等就是在此处触发代码生成。
- 在.class文件进一步优化成.dex文件时,也就是直接操作字节码文件。这种方式功能更加强大,应用场景也更多。但是门槛比较高,需要对字节码有一定的理解。
插桩的应用场景
一般情况下,我们会应用编译插桩进行如下的工作:
- 日志埋点;
- 性能监控;
- 动态权限控制;
- 业务逻辑跳转时,校验是否已经登录;
- 甚至是代码调试等。
总结一下,就是类似的操作(代码),需要在相同的场景下(比如Activity的生命周期onCreate)执行,常规的2种做法:
- 每个场景下进行添加代码
- 写一个基础类,让所有需要这种操作的去继承这个类
编译插桩是会让我们更加优雅地解决此类型的问题的方法。
插桩的工具
目前市面是流行的工具主要为2种:
AspectJ
AspectJ 是老牌 AOP(Aspect-Oriented Programming)框架。
其主要优势是成熟稳定,使用者也不需要对字节码文件有深入的理解。
ASM
ASM越来越受到广大工程师的喜爱。通过ASM可以修改现有的字节码文件,也可以动态生成字节码文件,并且它是一款完全以字节码层面来操纵字节码并分析字节码的框架。
不过也不用担心,用工具可以帮助我们生成字节码指令。
网上有很多ASM的使用方法,感兴趣的同学可以深入学习一下。
补充一点:
什么是AOP?
把这些横跨并嵌入众多模块里的功能(如监控每个方法的性能) 集中起来,放到一个统一的地方来控制和管理。
能给我带来什么:不修改源代码的情况下给程序动态统一添加功能的一种技术,把散落在程序中的公共部分提取出来,做成切面类,这样的好处在于,代码的可重用,一旦涉及到该功能的需求发生变化,只要修改该代码就行,否则,你要到处修改,如果只要修改1、2处那还可以接受,万一有1000处呢。
网友评论