我是名不见经传的ASM,你可能听说过我,也可能根本不认识我。但如果你认为我什么都不是,那你就错了。没有我,你经常用Spring,hibernate会失去最核心的功能。没有我,Jython,JRuby根本无法移植到Java虚拟机中。Clojure、Groovy等时下流行的语言,Java虚拟机里跑不了我。一句话概括我的能力:我可以动态修改编译类,也可以动态生成新的java类,注意我说的动态这个词,运行时完全可以在内存中完成,这是一个非常强大的技能。既然天生就是动态修改class文件,那为什么叫ASM呢?事实上,当我的造物主创造我时,为我取名花了很多功夫。然后他突然想到了C语言中的关键字__asm__,可以让你用C语言写一些汇编,他就挪用了关键字ASM。考虑到起名字确实是一件很折磨人的事情,我也就忍了,把这个叫做ASM,至少能体现出我在系统的顶层,不,应该说是最底层。听到下面有人问,不就是动态生成类吗?我可以使用JavaComplier接口在运行时像jsp一样动态编译一个java源代码。这不也是动态生成类吗?其实不一样,你的是生成一个新的class,现有的class可以修改吗?有人又说了,为什么要在运行时动态修改类呢?为什么不能在编译前把类的所有函数都写完?当然,如果你能把所有的功能都写好,那很好,但人生不如意,十之八九。举个最极端的例子,你从别人那里得到了一个没有源代码的jar文件,你想增强其中的一个类,怎么办?你可能会说:我可以反编译它。。算了,反编译后的代码你看得懂吗?而你常说的AOP,在配置文件中声明一些事务支持等功能,然后将这些功能动态编织到业务代码中,怎么办?有人说我可以用Java动态代理,是的,你可以用,但是如果人家没有接口,不还得盯着看发愁吗?对了,你的AOP术语真烂,什么PointCut,什么Advice,除了让人一头雾水,还有什么用?对了,还有那个Hibernate,你不知道那个所谓的实体类是我增强的吗?你用的不是你看到的,明白吗?如何动态修改类?其实很简单。下载一份Java虚拟机规范,花半年时间,一个字一个字看懂。***像黑客帝国里的Neo,你看到的整个世界都是二进制流,你自然会明白我是怎么做到的。简单说一下:我的核心主要是三个类,ClassReader,ClassWriter,ClassVisitor,你可以用这三个家伙来解析一个类的字节码,获取字段,方法等信息,当然最重要的是修改信息最终形成一个代表新类的字节码数组。你可能知道如何做剩下的,但它不再属于我了。还是不知道?很简单,就是用一个ClassLoader把这个字节码数组加载到虚拟机中,然后通过反射调用,不就完了吗?顺便说一句,我的创作者使用访客模式设计了这个API,说实话,设计得很好。细节太多,这里就不赘述了,有兴趣的同学可以看看(http://download.forge.objectweb.org/asm/asm4-guide.pdf),绝对值得有钱,当然你英文要好。说了这么多,再补充一点代码,让大家对我有一个直观的认识:估计你们看不懂,其实就是helloworld:你们心里可能在想,兄弟这个词,需要花很多时间使用ASM的努力。深入了解Java虚拟机指令和Java虚拟机内部结构即可使用。没错,我刚才说了,你需要了解Java虚拟机规范。我负责处理最基本的事情。很多coder不会直接拿我来编程。一个叫CGLib的人在我的基础上做了一个很好的包。他做了一些高层的API抽象,让普通的程序员可以很容易的修改一个现成的类的行为。因为更容易使用,所以CGLib的用户也比较多,像Spring,Hibernate。..我完全黯然失色,我想这就是我如此低调和默默无闻的原因。但是我没有改变初衷,坚持把字节码操作在顶层。我不断优化,让自己更小更快,为其他软件提供最强大的支持。我一开始说的是Clojure吧?这是一种无需编译过程即可解释和执行的函数式编程语言。那为什么它可以在Java虚拟机上运行呢?不就是用我的ASM动态生成词吗?部门代码?Jython、JRuby、Groovy都是类似的。最近,Java帝国授予我特殊贡献勋章,以奖励我为Java虚拟机市场的繁荣做出的重大贡献。毫不客气地说,这绝对是名副其实的。原来JVM中只有一种语言,那就是Java。你看现在好像没有多少语言可以选择了。好了,今天就到这里吧,下次再见。【本文为专栏作家“刘欣”原创稿件,转载请通过作者微信获取授权公众号coderising】点此查看该作者更多好文
