- 浏览: 271140 次
- 性别:
- 来自: 杭州
最新评论
-
qiumin333:
所以正数最大位0111 1111,也就是数字127, 负数最 ...
Java byte数据类型详解 -
weizhikang1992:
[b][flash=200,200][list][*]引用[/ ...
Java中AOP技术详解 -
lizhengzy:
[啊啊啊]
Java中AOP技术详解 -
iyaodi:
呃,错了,按位与0xff不等于*(-255)
Java byte数据类型详解 -
iyaodi:
ftutor 写道"即0xffffffff但是这个数 ...
Java byte数据类型详解
什么是asm呢?asm是assembly的缩写,是汇编的称号,对于java而言,asm就是字节码级别的编程。 而这里说到的asm是指objectweb asm,一种.class的代码生成器的开源项目. ASM是一套java字节码生成架构,它可以动态生成二进制格式的stub类或其它代理类, 或者在类被java虚拟机装入内存之前,动态修改类。 现在挺多流行的框架都使用到了asm.所以从aop追溯来到了这。 1.什么是ObjectWeb ASM ObjectWeb ASM是轻量级的Java字节码处理框架。它可以动态生成二进制格式的stub类或其他代理类,或者在类被JAVA虚拟机装入内存之前,动态修改类。 ASM 提供了与 BCEL和SERP相似的功能,只有22K的大小,比起350K的BCEL和150K的SERP来说,是相当小巧的,并且它有更高的执行效率, 是BCEL 的7倍,SERP的11倍以上。 在我看来,ObjectWeb ASM具有如下几个非常诱人的特点 * 小巧、高效 * 源代码实现非常简洁而又优雅,简直就是Gof的《设计模式》非常棒的注解 * 字节码级的控制,能够更高效地实现字节码的控制 ObjectWeb ASM有2组接口: * 基于事件驱动的接口,类似于xml的SAX接口,visitor模式,在访问到类定义某个部分的时候进行回调,实现上比tree接口高效,占用内存更小 * 基于tree的接口,类似于xml的DOM接口,将类定义解析成tree 这里我们将使用ObjectWeb ASM的事件驱动接口 2. 目标 我们将对已有的字节码进行增强,收集进入方法和退出方法的信息,这里主要解决Method Monitor的字节码增强部分, 不对收集后的数据处理做更深入地研究,出于演示的目的,我们定义了如下的收集方法的访问信息处理, 在实际应用中,我们可能会使用更好的格式收集更多的数据、使用异步处理提高性能、使用批量处理提高处理能力、使用友好的UI显示信息等等, 此处不对这部分进行探讨 1. package blackstar.methodmonitor.instrutment.monitor; 2. public class MonitorUtil 3. { 4. public final static String CLASS_NAME = MonitorUtil.class.getName() 5. .replaceAll("\\.", "/"); 6. public final static String ENTRY_METHOD = "entryMethod"; 7. public final static String EXIT_METHOD = "exitMethod"; 8. public final static String METHOD = "(Ljava/lang/String;Ljava/lang/String;)V"; 9. 10. public static void entryMethod(String className, String methodName) 11. { 12. System.out.println("entry : " + className + "." + methodName); 13. } 14. 15. public static void exitMethod(String className, String methodName) 16. { 17. System.out.println("exit : " + className + "." + methodName); 18. } 19. } 3. 从字节码开始 实际上,对于被监控制的代码,我们所需要实现的功能如下,红色部分的代码是我们需要在动态期插到字节码中间的 public xxx method(…) { try { methodEntry(…) methodCode } finally { methodExit(…) } } 这个问题看起来简单,实际则没有那么容易,因为在JVM的字节码设计中,字节码并不直接支持finally语句,而是使用try…catch来模拟的,我们先来看一个例子 Java代码 1. package blackstar.methodmonitor.instrutment.test; 2. 3. public class Test 4. { 5. public void sayHello() throws Exception 6. { 7. try 8. { 9. System.out.println("hi"); 10. } catch (Exception e) 11. { 12. System.out.println("exception"); 13. return; 14. } finally 15. { 16. System.out.println("finally"); 17. } 18. } 19. } 我们看看字节码是如何处理finally语句的 首先看看异常表,异常是在JVM级别上直接支持的,下面异常表的意思是,在执行0-8语句的时候,如果有异常java.lang.Exception抛出,则进入第11语句, 在执行0-20语句的时候,有任何异常抛出,都进入29语句。实际上JVM是这样实现finally语句的: * 在任何return语句之前,都会增加finally语句中的字节码 * 定义一个捕获所有异常的语句,增加finally语句中的字节码,如果finally中没有return语句,则会将异常再次抛出去(处理方法以抛出异常的方式结束) Exceptions: [0-8): 11 - java.lang.Exception [0-20): 29 我们再看看字节码具体是如何做的 0 getstatic java.lang.System.out 3 ldc "hi" (java.lang.String) 5 invokevirtual println 8 goto 40 // System.out.println("hi");,执行完之后执行返回(goto 40) 11 astore_1 12 getstatic java.lang.System.out 15 ldc "exception" (java.lang.String) 17 invokevirtual println // System.out.println("exception"); 20 getstatic java.lang.System.out 23 ldc "finally" (java.lang.String) 25 invokevirtual println // return语句之前插入finally部分字节码 // System.out.println("finally"); 28 return 29 astore_2 30 getstatic java.lang.System.out 33 ldc "finally" (java.lang.String) 35 invokevirtual println 38 aload_2 39 athrow //当在执行0-29语句中,如果有异常抛出,则执行这段finally语句 //此处的astore_2(将栈顶值——即exception的地址——设给第2个local变量)和aload_2(将第2个local变量的值入栈)这两个字节码实际是不必要的, //但需要注意的是,如果这2段代码去掉的话,要考虑增大操作栈(max stack)以容纳这个exception地址 //System.out.println("finally"); 40 getstatic java.lang.System.out 43 ldc "finally" (java.lang.String) 45 invokevirtual println // return语句之前插入finally部分字节码 // System.out.println("finally"); 48 return 实际上,我们需要做的就是 * 在方法进入时插入方法进入代码(需要注意,对于构造函数不允许做这种处理,构造函数第一步必须调用父类的构造函数。 * 在每个return操作(包括return、ireturn、freturn等)之前,插入方法退出代码 * 定义一个捕获所有异常的处理,在处理中,插入方法退出代码(即方法以抛异常的方式终止执行) 4. 实现 我们看看使用ObjectWeb ASM如何实现我们上面描述的功能 1)ObjectWeb ASM的字节码修改 1. ClassReader cr = new ClassReader(byteArray); //使用字节码构监一个reader 2. ClassWriter cw = new ClassWriter(cr, 0);//writer将基于已有的字节码进行修改 3. MonitorClassVisitor ca = new MonitorClassVisitor(cw);//修改处理回调类 4. cr.accept(ca, 0);
发表评论
-
java 序列化的说明
2013-01-23 13:49 1059当父类继承Serializable接口,所有子类都可以被序列 ... -
String.split() 需要注意的问题
2012-07-31 12:29 930特殊的分割符号:| * + \ \\ 在使用Str ... -
Object中getClass()方法详解
2012-07-31 12:29 29708Obejct类有一个getClass()方法: 返回 ... -
JVM运行时内存分配
2012-07-31 12:31 1930Inside JVM运行时数据区 ============ ... -
JRE 与 JDK ,JVM Client Server了解
2012-07-31 12:37 1156JRE 与 JDK ,JVM Client Server ... -
Java字符串及其编码
2012-07-31 12:37 1313编码:将字符以编码 ... -
Java中AOP技术详解
2012-08-01 23:48 20755AOP是Aspect Oriented Programm ... -
Java源代码文件与public类同名
2012-08-01 23:47 1103java源文件的命名规则是这样的: 1,扩展名必须 ... -
Java异常体系结构详解
2012-08-01 23:47 2055Java所有Exception, Error的父接口:T ... -
Java 线程栈信息详解
2012-08-01 23:48 5189windows系统中: 进程所拥有的内存空间都是独立 ... -
Java 启动类
2012-08-02 12:34 1093Launcher是JRE中用于启动程序入口main()的类。 -
Java 内存泄露浅析
2012-08-02 12:35 1686Java使用有向图的方 ... -
Java命令java, javac, jar
2012-08-02 12:35 2332java 用法: (执行 ... -
Java 进程,线程退出问题
2012-07-30 22:49 0Java的Main所在的线程启动一个新的线程以后,两个线 ... -
Java 环境变量详解
2012-08-02 12:35 1258当我们在Windows系统上安装jdk或者jre之后。 必须 ... -
Java 线程Thread详解
2012-08-02 12:35 2198在Java中,实现多线程的 ... -
Java的局部内部类以及final类型的参数和变量
2012-07-30 19:27 0如果定义一个局部内部类,并且希望它使用一个在其外部定的对 ... -
Java的transient, volatile, strictfp关键字详解
2012-07-30 19:26 0Java中的transient,volati ... -
Java代理模式,代理类(Proxy)详解
2012-07-30 19:24 0Java代理模式 1.代理模式 代理模式的作用是: ... -
Java常用jar包信息和关系介绍
2012-07-30 19:22 0Java发送邮件需要的jar包: mail.jar ac ...
相关推荐
ASM是一个底层的Java字节码操控和分析框架,它可以用来动态生成类或者增强已有类的功能。ASM提供了一套非常底层的API,可以精确地控制类和方法的生成,但同时也需要编写更复杂的代码。ASM主要用于库开发者,而不是...
ASM Tree库则是ASM框架中用于构建和解析抽象语法树(Abstract Syntax Tree, AST)的模块,对于理解、修改和生成Java类的字节码有着至关重要的作用。 在Java世界里,字节码是Java类的二进制表示形式,它是由JVM执行...
Dexposed框架详解 Dexposed是一款针对Android平台的运行时插件化框架,它允许开发者在不修改原生APK的情况下对应用进行功能增强或修复。这一框架的出现,为开发者提供了一种灵活的解决方案,尤其是在处理紧急的热...
使用 CGLIB 创建代理对象,我们需要引入 cglib-nodep-xxx.jar 包,并依赖于 ASM 库。CGLIB 是通过继承目标类的方式来实现动态代理的,因此目标类不能为 final 类。这里不再详细介绍 CGLIB 的具体实现,因为它相比 ...
ASM Tree库是Java开发者在处理字节码操作时经常会用到的一个工具库,它作为ASM框架的一部分,为开发者提供了一种方便的方式来解析和构建抽象语法树(Abstract Syntax Tree, AST)。ASM是一个Java字节码操控和分析...
总结,ASM Tree 3.2是ASM框架中用于处理字节码为树形结构的重要组件,它的稳定性和高效性使其在许多Java开发场景中得到广泛应用。通过理解其核心概念、版本特性以及实践操作,开发者能够更好地利用ASM Tree来实现...
ASM是一个Java字节码操控和分析框架,它可以直接解析和生成Java类文件,而ASM Tree库则是ASM框架的一部分,它提供了将字节码转换为抽象语法树(AST)的能力,进而便于进行代码分析和修改。本文将详细介绍ASM Tree ...
ASM-Util是ASM框架的一个辅助工具集,提供了更方便的API,使得开发者可以更加轻松地操作Java字节码。在本文中,我们将深入探讨ASM-Util 3.2版本中的核心概念、功能及使用方法。 首先,ASM-Util 3.2是一个与ASM主库...
ASM是一个Java字节码操控和分析框架,它可以直接用来动态生成类或者增强已有类的功能。在Java开发领域,ASM库因其强大的字节码操作能力而备受青睐,尤其在AOP(面向切面编程)、代码生成以及动态代理等场景中有着...
《ASM实用工具库ASM-Util 2.0详解》 ASM-Util 2.0.jar.zip是一个包含ASM库实用工具的压缩文件,主要用于Java字节码操作。在深入探讨ASM-Util 2.0之前,我们需要先理解ASM库的基础概念。 ASM是一个Java字节码操控和...
《ASM库在Java开发中的应用详解》 ASM是一款强大的Java字节码操控和分析框架,它的全称为ASM-all-4.0.jar。这个版本的ASM集成了所有必要的模块,为开发者提供了一站式的字节码操作解决方案。在本文中,我们将深入...
《ASM与XML在Java开发中的应用及asm-xml-2.2.1.jar.zip详解》 在Java开发中,ASM和XML是两个重要的组件,它们分别在不同的领域发挥着关键作用。ASM是一个Java字节码操控和分析框架,而XML则是用于数据交换的标准...
而ASM Tree库则是ASM框架的一部分,它提供了将字节码转换为抽象语法树(Abstract Syntax Tree, AST)的能力,方便开发者对Java代码进行解析、理解和操作。本文将深入探讨ASM Tree库3.3版本的主要特性和使用方法。 ...
### SSH配置与Java三个框架联合开发详解 #### 一、SSH框架概述 SSH框架是指Spring、Struts2和Hibernate三个框架的组合应用。这三种技术分别解决了企业级应用中的业务逻辑层管理、Web表现层以及数据访问层的问题,...
### Java开源项目Hibernate包作用详解 #### 概述 Hibernate是一个强大的对象关系映射(Object-Relational Mapping,简称ORM)框架,它极大地简化了Java应用程序与数据库交互的过程。通过Hibernate,开发者能够更加...
Java 动态代理是 Java 编程语言中的一种强大工具,广泛应用于 Spring AOP、Hibernate 数据查询、测试框架的后端 mock、RPC 远程调用、Java 注解对象获取、日志、用户鉴权、全局性异常处理、性能监控等领域。...
ASM是一个Java字节码操控和分析框架,它可以用来动态生成类或者增强已有类的功能。在shrinker项目中,ASM被用来遍历和修改字节码,找出R类中的常量整型字段,并进行内联操作。内联是一种优化技术,它将函数调用替换...
ASM是一个流行的开源Java字节码操纵和分析框架,而XML则是可扩展标记语言,广泛用于数据交换和存储。这个zip包的版本号为2.1,可能意味着它是该库的一个特定版本,针对某些功能进行了优化或修复了已知问题。 **ASM...
ASM是一个Java字节码操控和分析框架,它能够用来动态生成类或者增强已有类的功能。这个框架的核心在于它能够直接操作Java字节码,提供了一种低级别的手段来理解和修改类和方法。ASM库在Java开发中的主要用途包括代码...