package com.shihuan.method; public class AccountMethod { String sql = "select * from tables"; public AccountMethod() { } public AccountMethod(String sql) { super(); this.sql = sql; } public void operation() { System.out.println("shihuan operation..."); } int executeInternal() { System.out.println("shihuan executeInternal..."); if (true) { System.out.println(this.sql); return 2; } return 3; } }
package com.shihuan.method; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; 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; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import org.objectweb.asm.commons.Method; public class AsmAddMethod { public static void main(String[] args) throws IOException { ClassReader cr = new ClassReader("com.shihuan.method.AccountMethod"); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw){}; cr.accept(cv, Opcodes.ASM5); //新增加一个方法 MethodVisitor mw= cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "add", "([Ljava/lang/String;)V", null, null); // pushes the 'out' field (of type PrintStream) of the System class mw.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); // pushes the "Hello World!" String constant mw.visitLdcInsn("this is add method print!"); // invokes the 'println' method (defined in the PrintStream class) mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); mw.visitInsn(Opcodes.RETURN); // this code uses a maximum of two stack elements and two local // variables mw.visitMaxs(0, 0); mw.visitEnd(); byte[] code = cw.toByteArray(); OutputStream fos = new FileOutputStream("D:/myworkspace/JavaAsm/bin/com/shihuan/method/AccountMethod.class"); fos.write(code); fos.close(); } }
package com.shihuan.method; 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 AsmDeleteMethod { public static void main(String[] args) throws IOException { ClassReader cr = new ClassReader("com.shihuan.method.AccountMethod"); 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) { if("executeInternal".equals(name)) { return null; } return super.visitMethod(access, name, desc, signature, exceptions); //不为null,保留 } }; cr.accept(cv, ClassReader.SKIP_DEBUG); byte[] code = cw.toByteArray(); OutputStream fos = new FileOutputStream("D:/myworkspace/JavaAsm/bin/com/shihuan/method/AccountMethod.class"); fos.write(code); fos.close(); } }
AsmAddMethod2.java这种方式会清空掉AccountMethod.java文件中的所有内容,然后加入新方法,一般用的情况比较少。
package com.shihuan.method; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import org.objectweb.asm.commons.Method; public class AsmAddMethod2 { public static void main(String[] args) throws IOException { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cw.visit(38, Opcodes.ACC_PUBLIC, "com.shihuan.method.AccountMethod", null, "java/lang/Object", null); Method m = Method.getMethod("void <init> ()"); GeneratorAdapter ga = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null, null, cw); ga.loadThis(); ga.invokeConstructor(Type.getType(Object.class), m); ga.returnValue(); ga.endMethod(); m = Method.getMethod("void doSomething()"); ga = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null, null, cw); ga.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class)); ga.push("动态生成,动态加载调用方法"); ga.invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println(String)")); ga.returnValue(); ga.endMethod(); byte[] code = cw.toByteArray(); OutputStream fos = new FileOutputStream("D:/myworkspace/JavaAsm/bin/com/shihuan/method/AccountMethod.class"); fos.write(code); fos.close(); } }