- 浏览: 753130 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
lgh1992314:
a offset: 26b offset: 24c offse ...
java jvm字节占用空间分析 -
ls0609:
语音实现在线听书http://blog.csdn.net/ls ...
Android 语音输入API使用 -
wangli61289:
http://viralpatel-net-tutorials ...
Android 语音输入API使用 -
zxjlwt:
学习了素人派http://surenpi.com
velocity宏加载顺序 -
tt5753:
谢啦........
Lucene的IndexWriter初始化时的LockObtainFailedException的解决方法
接之前的博客http://zhwj184.iteye.com/admin/blogs/1630756 关于asm使用的示例,这次使用asm来动态统计每个方法的执行时间,实现AOP功能。
AOP的更通用的做法是对原始类动态生成子类,调用子类的方法覆盖父类,来实现AOP的功能。著名的 Hibernate 和 Spring 框架,就是使用这种技术实现了 AOP 的“无损注入”。
下面我们就通过一个示例来对方法Foo.execute调用时动态注入方法执行前后的时间统计来统计方法的执行时间
import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; public class AsmAopExample extends ClassLoader implements Opcodes{ public static class Foo { public static void execute() { System.out.println("test changed method name"); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static class Monitor{ static long start = 0; public static void start(){ start = System.currentTimeMillis(); } public static void end(){ long end = System.currentTimeMillis(); System.out.println("execute method use time :" + (end - start)); } } public static void main(String[] args) throws IOException, IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException { ClassReader cr = new ClassReader(Foo.class.getName()); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); ClassVisitor cv = new MethodChangeClassAdapter(cw); cr.accept(cv, Opcodes.ASM4); // gets the bytecode of the Example class, and loads it dynamically byte[] code = cw.toByteArray(); AsmAopExample loader = new AsmAopExample(); Class<?> exampleClass = loader.defineClass(Foo.class.getName(), code, 0, code.length); for(Method method: exampleClass.getMethods()){ System.out.println(method); } exampleClass.getMethods()[0].invoke(null, null); //調用execute,修改方法內容 // gets the bytecode of the Example class, and loads it dynamically FileOutputStream fos = new FileOutputStream("e:\\logs\\Example.class"); fos.write(code); fos.close(); } static class MethodChangeClassAdapter extends ClassVisitor implements Opcodes { public MethodChangeClassAdapter(final ClassVisitor cv) { super(Opcodes.ASM4, cv); } @Override public MethodVisitor visitMethod( int access, String name, String desc, String signature, String[] exceptions) { if("execute".equals(name)) //此处的execute即为需要修改的方法 ,修改方法內容 { MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);//先得到原始的方法 MethodVisitor newMethod = null; newMethod = new AsmMethodVisit(mv); //访问需要修改的方法 return newMethod; } return null; } } static class AsmMethodVisit extends MethodVisitor { public AsmMethodVisit(MethodVisitor mv) { super(Opcodes.ASM4, mv); } @Override public void visitCode() { //此方法在访问方法的头部时被访问到,仅被访问一次 visitMethodInsn(Opcodes.INVOKESTATIC, Monitor.class.getName(), "start", "()V"); super.visitCode(); } @Override public void visitInsn(int opcode) { //此方法可以获取方法中每一条指令的操作类型,被访问多次 //如应在方法结尾处添加新指令,则应判断: if(opcode == Opcodes.RETURN) { visitMethodInsn(Opcodes.INVOKESTATIC, Monitor.class.getName(), "end", "()V"); } super.visitInsn(opcode); } } }
输出:
public static void AsmAopExample$Foo.execute() public native int java.lang.Object.hashCode() public final native java.lang.Class java.lang.Object.getClass() public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException public final void java.lang.Object.wait() throws java.lang.InterruptedException public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException public boolean java.lang.Object.equals(java.lang.Object) public java.lang.String java.lang.Object.toString() public final native void java.lang.Object.notify() public final native void java.lang.Object.notifyAll() test changed method name execute method use time :10
可以看到在execute方法中sleep 10ms,这里打印出来也是10ms,这里是在execute方法执行前先调用monitor.start()方法,方法返回是调用monitor的end方法,从而达到统计的功能,不过这里只是一个示例,如果要统计每个方法的执行时间,统计并发进行方法统计时这里当然要进行扩展,不过思路差不多就是这样。
我们查下最终生成的Foo类的class文件通过反射后的源代码:
import java.io.PrintStream; public class AsmAopExample$Foo { public static void execute() { AsmAopExample.Monitor.start(); System.out.println("test changed method name"); try { Thread.sleep(10L); } catch (InterruptedException e) { e.printStackTrace(); } AsmAopExample.Monitor.end(); } }
大家可以参考这里的一篇比较全的文章:http://www.ibm.com/developerworks/cn/java/j-lo-asm30/
发表评论
-
对字符串进行验证之前先进行规范化
2013-09-17 23:18 13947对字符串进行验证之前先进行规范化 应用系统中经常对字 ... -
使用telnet连接到基于spring的应用上执行容器中的bean的任意方法
2013-08-08 09:17 1471使用telnet连接到基于spring的应用上执行容器中 ... -
jdk7和8的一些新特性介绍
2013-07-06 16:07 10110更多ppt内容请查看:htt ... -
java对于接口和抽象类的代理实现,不需要有具体实现类
2013-06-12 09:50 2952原文链接:http://www.javaarch.net/j ... -
Excel2007格式分析和XML解析
2013-06-07 09:56 10728在物料清单采购中,用到excel上传文件解析功能,不 ... -
Java EE 7中对WebSocket 1.0的支持
2013-06-05 09:27 3837原文链接:http://www.javaarch.n ... -
java QRCode生成示例
2013-06-05 09:26 1510原文链接:http://www.javaarch.n ... -
Java Web使用swfobject调用flex图表
2013-05-28 19:05 1121Java Web使用swfobject调用 ... -
spring使用PropertyPlaceholderConfigurer扩展来满足不同环境的参数配置
2013-05-21 15:57 3332spring使用PropertyPlaceholderCon ... -
java国际化
2013-05-20 20:57 4472java国际化 本文来自:http://www.j ... -
RSS feeds with Java
2013-05-20 20:52 1214RSS feeds with Java 原文来自:htt ... -
使用ibatis将数据库从oracle迁移到mysql的几个修改点
2013-04-29 10:40 1674我们项目在公司的大战略下需要从oracle ... -
线上机器jvm dump分析脚本
2013-04-19 10:48 2905#!/bin/sh DUMP_PIDS=`p ... -
eclipse远程部署,静态文件实时同步插件
2013-04-06 20:18 5460eclipse 远程文件实时同步,eclipse远程 ... -
java价格处理的一个问题
2013-03-26 21:21 1829我们经常会处理一些价格,比如从运营上传的文件中将某 ... -
java 服务降级开关设计思路
2013-03-23 16:35 3764java 服务屏蔽开关系统,可以手工降级服务,关闭服 ... -
poi解析excel内存溢出
2013-03-20 22:21 6397真是悲剧啊,一个破内部使用系统20多个人使用的后 ... -
简单web安全框架
2013-03-16 11:56 1543web安全框架,主要用servlet filter方 ... -
基于servlet的简单的页面缓存框架
2013-03-11 19:27 1215基于servlet的页面级缓存框架的基本用法: 代码参考: ... -
Eclipse使用过程中出现java.lang.NoClassDefFoundError的解决方案
2013-02-01 17:22 1572如果jdk,classpath设置正确,突然在eclipse ...
相关推荐
内容包含ASM4.0中文手册,以及四种ASM常见的字节码操作应用范例,包含最新版本的ASM9.2的jar包,包含asm-9.2.jar,asm-commons-9.2.jar,asm-util-9.2.jar。 学习文章地址 ...
标题中的“asm4.0全家福”指的是ASM库的一个完整版本集合,ASM是一个Java字节码操控和分析框架,主要用于动态生成类或者增强已有类的功能。这个“全家福”包括了ASM库的主要组件,分别是: 1. **asm-4.0**: 这是ASM...
ASM是一个强大的Java字节码操控...总的来说,ASM4.0_RC1是一个强大的工具,为Java开发者提供了一种底层操控字节码的方式,使得在运行时生成和修改类成为可能,从而在诸如AOP、插件系统、代码生成等领域具有广泛的应用。
标题中的"asm-tree-4.0.zip_asm4.0"提到了ASM库的特定版本,ASM是一个Java字节码操控和分析框架,主要用于动态代理、字节码转换以及代码分析等场景。ASM 4.0是这个库的一个版本,可能包含了一些针对性能和功能的改进...
ASM 4 使用指南中文版。ASM是Java字节码的工业级库。长期以来一直没有中文版。这下好了,中文版横空出世。感兴趣的同学可以投递简历 mars # oneapm . com 常年有效 ASM 4.0 A Java bytecode engineering library
3. **创建 MethodVisitor**:针对每个方法,我们需要创建一个 MethodVisitor 对象,通过重写其方法,实现在字节码级别插入新的指令。 4. **插入切面代码**:在适当的位置,比如方法调用前(Advice Before)和调用后...
spring 3.2.5版本源码使用的,构建的时候使用如下描述 因为英文不太好,大概意思可能是什么asm4.0版本使用的spring 在spring4中已经重新包装了asm在spring-core的核心包里,当然我这解释不标准 看下满原文构建的描述...
标题中的"asm-util-4.0_RC1.jar.zip"是一个归档文件,它是一个ZIP格式的压缩包,其中包含了ASM工具库的一个特定版本——ASM Util 4.0 Release Candidate 1(RC1)。ASM是一个Java字节码操控和分析框架,广泛用于动态...
ASM库广泛应用于字节码级别的编程,例如在Java代理、代码混淆、性能监控以及动态语言实现等领域。 描述中提到了“asm, all, 4.0, jar.zip包下载, 依赖包”,这进一步解释了这个压缩包的内容。"asm"是指ASM库本身,...
下面通过一个具体的示例来展示如何使用ASM进行AOP的实现: 1. **创建一个安全检查类**: ```java public class SecurityChecker { public static void checkSecurity() { System.out.println("SecurityChecker....
asm-4.0.jar
4. **框架实现**:许多框架如Hibernate、Spring等,都使用ASM来实现元编程,动态生成类和方法。 ASM-4.0作为其重要版本,引入了一些新特性和改进: - 提高了API的易用性,使得开发者更容易地进行字节码操作。 - ...
- **定义与功能**:ASM是一个Java字节码操纵框架,主要用于动态生成类或增强现有类的功能。通过直接生成二进制`.class`文件,ASM能够在类被加载到Java虚拟机之前动态地改变类的行为。 - **应用场景**: - **程序...
JavaEE CGLIB字节码增强技术是实现面向切面编程(AOP)的一种常见方法。在JavaEE应用中,AOP允许开发者定义“切面”,这些切面封装了跨越多个对象的横切关注点,如日志、事务管理等。CGLIB(Code Generation Library...
ASM库是一个轻量级的Java字节码操控和分析框架,常用于动态代理、代码生成以及AOP实现。本篇文章将深入探讨如何使用ASM库来实现函数监听,特别是如何在函数执行前拦截并改变其参数值。 首先,我们需要理解ASM库的...
"asm-4.0_RC1.jar.zip" 是ASM库的4.0_RC1版本的压缩包,其中包含ASM的主要实现类和接口。 这个版本的ASM主要提供了以下几个方面的功能: 1. **字节码解析**:ASM能够解析Java字节码,将其转化为一棵抽象语法树...
Java字节码实现AOP(面向切面编程)是一种在程序运行时动态插入代码的技术,它使得我们可以在不修改原有代码的情况下,增加新的功能或监控已有功能。在Java中,AOP通常通过代理模式和字节码操作来实现,如Spring AOP...
在这个适配器中,我们需要重写visitMethod方法,该方法会在遇到类的每个方法时被调用。 2. **检测目标方法**: 在visitMethod方法内,我们需要根据业务需求,识别出需要插入埋点代码的目标方法。这可以通过方法名、...
赠送jar包:asm-4.2.jar; 赠送原API文档:asm-4.2-javadoc.jar; 赠送源代码:asm-4.2-sources.jar; 赠送Maven依赖信息文件:asm-4.2.pom; 包含翻译后的API文档:asm-4.2-javadoc-API文档-中文(简体)版.zip; ...