`
baobeituping
  • 浏览: 1071309 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

ASM实现类的AOP操作(实战篇-直接改写某一个类的.class文件)

阅读更多

1.首先写一个ACCOUNT类(业务逻辑类)

 

public class Account {

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

 

2.写一个执行安全日志的类类似AOP操作

 

public class SecurityChecker {
 
 public static void checkSecurity() {
  System.out.println("SecurityChecker.checkSecurity ...");
  //TODO real security check
 } 

}

3.写一个访问Account字节码文件的类

 

 

import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;

public class AddSecurityCheckClassAdapter extends ClassAdapter {

 public AddSecurityCheckClassAdapter(ClassVisitor cv) {
  super(cv);
  
 }

 
 public MethodVisitor visitMethod(int access, String name, String desc,
   String signature, String[] exceptions) {
  MethodVisitor mv = cv.visitMethod(access, name, desc, signature,exceptions);
  
    MethodVisitor wrappedMv = mv;
    if (mv != null) {
     //对于 "operation" 方法
     if (name.equals("operation")) {
      //使用自定义 MethodVisitor,实际改写方法内容
      wrappedMv = new AddSecurityCheckMethodAdapter(mv);
     }
    }
    return wrappedMv;

 }

}

4.写一个访问某个字节码文件中方法的类

 

 

import org.objectweb.asm.MethodAdapter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class AddSecurityCheckMethodAdapter extends MethodAdapter implements
  MethodVisitor {

 public AddSecurityCheckMethodAdapter(MethodVisitor mv) {
  super(mv);
  // TODO Auto-generated constructor stub
 }

 
 public void visitCode() {
  visitMethodInsn(Opcodes.INVOKESTATIC, "SecurityChecker",
    "checkSecurity", "()V");
 }

}

 

5.写一个整合类,将上面的类进行整合,并生成一个新的Account.class文件,该文件是被修改了方法的类文件,包含了安全检查方法

 

 

import java.io.File;
import java.io.FileOutputStream;

import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;

public class Generator {

 /**
  * @param args
  */
 public static void  main(String[] args) throws Exception {
  ClassReader cr = new ClassReader("Account");
  ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
  ClassAdapter classAdapter = new AddSecurityCheckClassAdapter(cw);
  cr.accept(classAdapter, ClassReader.SKIP_DEBUG);
  byte[] data = cw.toByteArray();
  File file = new File("D://workspace//ASM//WebRoot//WEB-INF//classes//Account.class");
  FileOutputStream fout = new FileOutputStream(file);
  fout.write(data);
  fout.close();


 }

}

6.写一个测试类,测试你新生成的Account.class

 

public class Test {
 public static void main(String[] args) {
  Account account = new Account();
  account.operation();


 }

}

7.得到的结果

 

SecurityChecker.checkSecurity ...
operation...

总结,该方法的核心思想就是利用ASM的API直接去修改某一个.class文件强行插入某段代码

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics