`
shihuan830619
  • 浏览: 583105 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java字节码实现Aop

    博客分类:
  • asm
阅读更多
以下代码需要asm-5.0.2.jar和asm-commons-5.0.2.jar两个包。

package com.shihuan.asm.account;

public class Account {
	
	public void operation() {
		System.out.println("shihuan operation...");
	}
	
}


package com.shihuan.asm.account;

public class SecurityChecker {

	public static void checkSecurity() {
		System.out.println("SecurityChecker.checkSecurity...");
	}
	
}


package com.shihuan.asm.account;

public class TestAccount {

	public static void main(String[] args) {
		Account a = new Account();
		a.operation();
	}

}


package com.shihuan.asm.account;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

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 AccountAsm {

	public static void main(String[] args) throws IOException {
		ClassReader cr = new ClassReader("com.shihuan.asm.account.Account");
		ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
		ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw){
			
			public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
				
				MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);  // 先得到原始的方法
				MethodVisitor newMethod = mv;
				
				if (mv != null) {
					if ("operation".equals(name)){ // 此处的operation即为需要修改的方法 ,修改方法內容
						// 访问需要修改的方法
						newMethod = new MethodVisitor(Opcodes.ASM5, mv) {
							
							public void visitCode() {
								visitMethodInsn(Opcodes.INVOKESTATIC, "com/shihuan/asm/account/SecurityChecker","checkSecurity", "()V", false);
								super.visitCode();
							}
							
						};
						
						
					}
				}
				
				return newMethod;
			}
			
			
			
		};
		cr.accept(cv, ClassReader.SKIP_DEBUG);
		
		byte[] code = cw.toByteArray();
		
		OutputStream fos = new FileOutputStream("D:/myworkspace/JavaAsm/bin/com/shihuan/asm/account/Account.class");
		fos.write(code);
		fos.close();
	}

}


----------------------------------------------------------------------------------
上面的代码是笔者测试Asm用的,下面笔者做一个抓取Oracle驱动包中原生态SQL语句的例子。
需要在工程中添加ojdbc6.jar文件。

package oracle.jdbc.driver;

public class OracleMyEnd {

	public static void getMySqlInfo(OraclePreparedStatement opsObj) {
		System.out.println("ShiHuan Is Sql --->> " + opsObj.sqlObject.originalSql);
	}
	
}


package oracle.jdbc.driver;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

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 OracleAsm {

	public static void main(String[] args) {
		try {
			ClassReader cr = new ClassReader("oracle.jdbc.driver.OraclePreparedStatement");
			ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
			ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw){
				
				public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
					
					MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);  // 先得到原始的方法
					MethodVisitor newMethod = mv;
					
					if (mv != null) {
						if ("executeInternal".equals(name)){ // 此处的executeInternal即为需要修改的方法 ,修改方法內容
							// 访问需要修改的方法
							newMethod = new MethodVisitor(Opcodes.ASM5, newMethod) {								
								public void visitCode() {
									visitVarInsn(Opcodes.ALOAD, 0);
									visitMethodInsn(Opcodes.INVOKESTATIC, "oracle/jdbc/driver/OracleMyEnd","getMySqlInfo", "(Loracle/jdbc/driver/OraclePreparedStatement;)V", false);
									super.visitCode();
								}
								
							};
						}
					}
					
					return newMethod;
				}
				
			};
			
			cr.accept(cv, ClassReader.SKIP_DEBUG);
			
			byte[] code = cw.toByteArray();
			
			OutputStream fos = new FileOutputStream("D:/myworkspace/JavaAsm/bin/oracle/jdbc/driver/OraclePreparedStatement.class");
			fos.write(code);
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
分享到:
评论

相关推荐

    JavaEE CGLIB字节码增强方式实现AOP编程

    ASM是一个底层的Java字节码操控和分析框架,可以用来动态生成类或者增强已有类的功能。 **CGLIB的使用步骤**: 1. 引入依赖:在项目中引入CGLIB的依赖库,通常通过Maven或Gradle等构建工具添加。 2. 创建Enhancer...

    java字节码编辑器

    Java字节码编辑器是一种工具,它允许开发者直接编辑Java程序编译后的`.class`文件,而不是反编译后再重新编译。这种编辑器对于理解、调试和优化Java代码非常有用,尤其是对于那些无法访问源代码或者需要进行底层操作...

    JAVA字节码操作库 BCEL

    **JAVA字节码操作库 BCEL** BCEL(Byte Code Engineering Library)是Java开发的一个重要工具,主要用于处理Java字节码。它为开发者提供了一种深入理解与操作Java类文件的底层机制,允许分析、创建、修改和优化字节...

    cglib,字节码生成库是生成和转换Java字节码的高级API。它被aop、测试、数据访问框架用来生成动态代理对象和拦截字段访问。.zip

    **CGlib:高级Java字节码生成库** CGlib(Code Generation Library)是一个强大的高性能的代码生成库,它主要用于在运行期扩展Java类与实现Java接口。这个库最初由Evan Schooler创建,后来成为Apache软件基金会的一...

    从一个class文件深入理解Java字节码结构

    通过深入了解这些结构,开发者可以更好地理解Java字节码的工作原理,从而优化代码执行效率,调试程序,甚至实现字节码级别的动态修改和插桩技术。这对于性能调优、AOP(面向切面编程)以及理解JVM的工作方式至关重要...

    该项目主要是JAVA字节码的学习项目.zip

    6. **字节码操纵**:Java字节码操纵库,如ASM、BCEL、CGLIB等,允许程序员在运行时动态修改类的字节码,实现AOP(面向切面编程)和代码注入等功能。 7. **安全性**:Java的字节码验证机制确保了字节码的安全性,...

    基于Java字节码增强技术实现的协程Demo.zip

    Java字节码增强技术是Java开发中的一种高级技巧,它允许开发者在程序运行时动态修改类的字节码,从而实现一些特殊的功能,比如AOP(面向切面编程)、性能监控、事务管理等。协程是一种轻量级的线程,它在执行过程中...

    Java字节码和asm入门资料

    Java字节码是Java虚拟机...总的来说,Java字节码和ASM是Java开发中的高级主题,它们对于理解Java运行机制、实现高性能的代码以及进行动态编程至关重要。通过学习和实践,开发者可以掌握这些技术,提升自己的编程能力。

    深入字节码 -- 使用 ASM 实现 AOP1

    Java 字节码理解为 JVM 能够识别的机器语言,它是 Java 源代码经过编译后的产物。每个字节码指令对应一个特定的操作,比如 `getstatic` 用于获取静态字段,`ldc` 加载常量,`invokevirtual` 调用虚方法等。JVM 会...

    ASM Java字节码操作框架

    ASM Java字节码操作框架PPT,结合已有AOP实现方法,对比所有对Java字节码操作方法做比较

    java字节码例子 可以动态修改类 bcel

    Java字节码是Java平台的...通过学习这些内容,开发者可以掌握Java字节码的基本操作,并利用BCEL在实际项目中实现高级功能。同时,这也是一种深入理解JVM工作原理的方式,有助于提升Java编程的技能和对底层机制的理解。

    javassist,Java字节码工程工具包.zip

    Java字节码工程工具包,通常被称为Javassist,是一个开源项目,专为Java开发者提供了一种方便的方式来处理和操作字节码。Javassist在Java应用开发中扮演着重要的角色,尤其是在动态代理、AOP(面向切面编程)以及...

    ASM操作字节码,动态生成Java类class文件

    ASM是一个开源的Java字节码操控和分析框架,它能够用来动态生成类或者增强已有类的功能。ASM可以被用来创建Java代理、实现元编程、甚至深入到Java虚拟机(JVM)层面进行性能优化。在Java开发中,ASM库允许我们直接...

    JAVA字节码操作库 BCEL.7z

    **JAVA字节码操作库 BCEL** BCEL(Byte Code Engineering Library)是Java平台上的一款开源库,主要用于处理Java字节码。它提供了对字节码的解析、创建、修改和分析的能力,使得开发者能够深入理解并操作Java类文件...

    JAVA字节码编辑工具.zip

    JAVA字节码编辑工具,正如其标题所示,是一种专门用于编辑Java字节码的软件。在Java编程语言中,源代码被编译成字节码(.class文件),这是一种平台无关的中间表示形式,可以在Java虚拟机(JVM)上运行。这个工具...

    java-用Java动态代理实现AOP.pdf

    对于有具体实现类的情况,可能需要使用其他AOP框架,比如Spring AOP,它基于字节码操作,能处理接口和类,功能更加强大和灵活。 总之,Java动态代理提供了一种在运行时创建代理类并实现AOP的方法,它可以帮助我们...

    java源码:JAVA字节码操作库 BCEL.zip

    Java字节码操作库BCEL(Byte Code Engineering Library)是一个强大的工具,用于分析、修改和创建Java类文件。它是Apache软件基金会的Jakarta项目的一部分,为开发者提供了对字节码的底层控制,使得开发者能够在运行...

Global site tag (gtag.js) - Google Analytics