Java编程的动态特性, 从Reflection到Runtime Class Transformation
2013-11-23 11:00
330 查看
关于Java编程的动态特性,从认识的过程上要从 Reflection 到 instrumentation。
1. 初步的开发者刚接触到Reflection会非常兴奋,因为反射可以在运行时完成很多之前不可能的任务,这件利器使人打破了很多束缚。
2. Java Annotation出现后,更让Java变得更加有活力,更加友好。Annotation + Reflection + enum + Class Literal可以让过去比较难于完成的任务容易很多,这种初步的元驱动的方式毕竟打开了元驱动的新天地。
3.进入元驱动的世界,把Java语言,这种编译型语言,不再作为指令和数据的表达方式,而作为元数据的表达方式,开启了一种奇特的开发领域特定脚本语言的经历,这已经很酷了。
4. 毕竟Java Reflection还有自己的开销。不仅性能损耗是直接invoke发生的近1000倍,而且对于面向方面编程还需要引入动态代理和接口,虽然后者可能也不算什么,毕竟大家这样做很久了。但是Java还是提供了更加动态和简洁的方式,那就是Instrumentation,可以运行时在装载Class到ClassLoader的过程中进行字节码转换。这项技术被很多知名的编程框架所采用(有的是在编译时修改字节码), 比如EJB3.X, JPA persistence provider runtime eclipselink, Hibernate,无所不能的测试框架jmockit等等。
那么如何入门Instrumentation呢?
学习Instrumenation需要了解以下几个主要方面: 1. JVM规范的bytecode的相关信息
2. JVM规范中Java Class Format
3. Instrumation框架
4. 受欢迎的几个类库: Javassist, BCEL
5. 学习过程中使用到的工具: javap, eclipse的byte code visualizer, vim等等
如何上手?
1. 入手的时候,建议首先通过javap命令观察几个自己熟知的比较小一点的类,对于class文件中的概念有一些感性认识,比如Constant Pool,Code, ACC_XXX等等,命令如下: javap -v -l -p -c -s -constants /demo/standalone/ServiceOrder\$1.class 2. 看了几个类文件之后,可以看一个模拟JVM执行的demo。这是比较早期的一本非常知名的书籍作者编写的一系列的applet, 这些demo都在“深入Java虚拟机第二版CD.zip”这个文件中,如果你无法使用浏览器打开这些applet,那么你可以用jdk自带的appletviewer命令打开这些网页。比如其中有一个关于JVM模拟执行bytecode的例子, 可以了解到LocalVariableTable和Operand Stack以及PC的概念 appletviewer EternalMath.html 3. 比较有感觉了以后,建议学习IBM developerworks上的《Java编程的动态性》这套教程,一共8个部分,介绍了从Reflection到Instrumentation的过程(其中介绍的Javassist和BCEL在运行时都是基于Instrumentation)。动手做一些教程中的例子,建议采用编译目标定为1.6,避免出现一些错误。教程地址:
http://www.ibm.com/developerworks/cn/java/j-dyn0610/index.html
4. 有实际这方面需要的时候,在采用Javassist或者BCEL这种类库工具外,还要自己设计class转换前或者转换后的样式。那么这时候以下这些信息会派上用场:
a. vim -b xxxx.class, 进入vim后使用%!xxd以16进制对照ASCII码观察字节码
b. 前面提到的javap命令观察比较转换前后的区别,以及和目标的区别,通常目标是一个手工写的并且编译过的class文件
c. 也可以通过eclipse的一个插件byte code visualizer来查看,他提供了两个字节码查看器。一个是类似javap的重点查看方法byte code的,而另一个是类似vim -b + %!xxd的16进制对照字节码的,但是提供了更多的信息。
d. 剩下的就是要参考JVM规范了,其中两章很常用 ,分别是 Class File Format和 Java Virtual Machine Instruction Set
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
1. 初步的开发者刚接触到Reflection会非常兴奋,因为反射可以在运行时完成很多之前不可能的任务,这件利器使人打破了很多束缚。
2. Java Annotation出现后,更让Java变得更加有活力,更加友好。Annotation + Reflection + enum + Class Literal可以让过去比较难于完成的任务容易很多,这种初步的元驱动的方式毕竟打开了元驱动的新天地。
3.进入元驱动的世界,把Java语言,这种编译型语言,不再作为指令和数据的表达方式,而作为元数据的表达方式,开启了一种奇特的开发领域特定脚本语言的经历,这已经很酷了。
4. 毕竟Java Reflection还有自己的开销。不仅性能损耗是直接invoke发生的近1000倍,而且对于面向方面编程还需要引入动态代理和接口,虽然后者可能也不算什么,毕竟大家这样做很久了。但是Java还是提供了更加动态和简洁的方式,那就是Instrumentation,可以运行时在装载Class到ClassLoader的过程中进行字节码转换。这项技术被很多知名的编程框架所采用(有的是在编译时修改字节码), 比如EJB3.X, JPA persistence provider runtime eclipselink, Hibernate,无所不能的测试框架jmockit等等。
那么如何入门Instrumentation呢?
学习Instrumenation需要了解以下几个主要方面: 1. JVM规范的bytecode的相关信息
2. JVM规范中Java Class Format
3. Instrumation框架
4. 受欢迎的几个类库: Javassist, BCEL
5. 学习过程中使用到的工具: javap, eclipse的byte code visualizer, vim等等
如何上手?
1. 入手的时候,建议首先通过javap命令观察几个自己熟知的比较小一点的类,对于class文件中的概念有一些感性认识,比如Constant Pool,Code, ACC_XXX等等,命令如下: javap -v -l -p -c -s -constants /demo/standalone/ServiceOrder\$1.class 2. 看了几个类文件之后,可以看一个模拟JVM执行的demo。这是比较早期的一本非常知名的书籍作者编写的一系列的applet, 这些demo都在“深入Java虚拟机第二版CD.zip”这个文件中,如果你无法使用浏览器打开这些applet,那么你可以用jdk自带的appletviewer命令打开这些网页。比如其中有一个关于JVM模拟执行bytecode的例子, 可以了解到LocalVariableTable和Operand Stack以及PC的概念 appletviewer EternalMath.html 3. 比较有感觉了以后,建议学习IBM developerworks上的《Java编程的动态性》这套教程,一共8个部分,介绍了从Reflection到Instrumentation的过程(其中介绍的Javassist和BCEL在运行时都是基于Instrumentation)。动手做一些教程中的例子,建议采用编译目标定为1.6,避免出现一些错误。教程地址:
http://www.ibm.com/developerworks/cn/java/j-dyn0610/index.html
4. 有实际这方面需要的时候,在采用Javassist或者BCEL这种类库工具外,还要自己设计class转换前或者转换后的样式。那么这时候以下这些信息会派上用场:
a. vim -b xxxx.class, 进入vim后使用%!xxd以16进制对照ASCII码观察字节码
b. 前面提到的javap命令观察比较转换前后的区别,以及和目标的区别,通常目标是一个手工写的并且编译过的class文件
c. 也可以通过eclipse的一个插件byte code visualizer来查看,他提供了两个字节码查看器。一个是类似javap的重点查看方法byte code的,而另一个是类似vim -b + %!xxd的16进制对照字节码的,但是提供了更多的信息。
d. 剩下的就是要参考JVM规范了,其中两章很常用 ,分别是 Class File Format和 Java Virtual Machine Instruction Set
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html
相关文章推荐
- Java编程的动态特性,使用BCEL代码生成工具,极大简化Class Transformation开发
- runtime动态定义的JavaBean:DynaBean,DynaClass,DynaProperty
- java动态加载jar,class
- java反射并不是什么高深技术,面向对象语言都有这个功能,而且功能也很简单,就是利用jvm动态加载时生成的class对象
- 【Java并发编程】:并发新特性—塞队列和阻塞栈
- ibatis中动态查询返回字段返回用resultClass="java.util.HashMap" 的问题
- 在什么样的场景下,需要利用到Java的反射特性编程?
- java.lang.RuntimeException: Parcelable encounteredClassNotFoundException reading a Serializable obje
- 关于使用动态代理创建代理对象是报错 java.lang.ClassCastException: $Proxy0 cannot be cast to 的解决办法
- jgroups gossipRouter 报错 java.lang.RuntimeException: class for magic number -1 not found
- java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldExceptio
- ibatis中动态查询表返回用resultClass="java.util.HashMap" 的问题
- Java中class文件的动态加载
- Java动态编程之javassist
- iOS 动态特性和RunTime
- Java运行时动态加载类之ClassLoader
- java.lang.RuntimeException: Invalid action class configuration that references an unknown class name
- Android “java.lang.RuntimeException: Parcelable encounteredClassNotFoundException reading a Serializ
- 【Java并发编程】并发新特性—Lock锁和条件变量(含代码)
- JAVA AOP编程之动态代理技术