java 动态AOP
来源:互联网 发布:开淘宝怎么交保证金 编辑:程序博客网 时间:2024/05/16 17:41
一、實現機制:
在运行期,所有类加载器加载字节码前,前进行拦截。並將代碼植入。可以对所有类进行织入。
二、實現方式:
1. 實現ClassFileTransformer 接口
2. 添加以下方法(必須):
public static void premain(String options, Instrumentation ins) { //注册我自己的字节码转换器 ins.addTransformer(new MyClassFileTransformer()); }
實例:
package com.aop;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
public class AopTransformer implements ClassFileTransformer {
/**
* 字节码加载到虚拟机前会进入这个方法
*/
@Override
public byte[] transform(ClassLoader loader, String className,
Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException {
// javassist的包名是用点分割的,需要转换下
if (className.indexOf("/") != -1) {
className = className.replaceAll("/", ".");
}
try {
// 通过包名获取类文件
CtClass cc = ClassPool.getDefault().get(className);
// 获得指定方法名的方法
CtMethod m = cc.getDeclaredMethod("sayhello");
// 在方法执行前插入代码
m.insertBefore("{System.out.println(\"在HelloTest.sayhello之前執行\");}");
m.insertAfter("{System.out.println(\"在HelloTest.sayhello之後執行\");}");
m = cc.getDeclaredMethod("sayGoodBye");
// 在方法执行前插入代码
m.setBody("{System.out.println(\"修改HelloTest.sayGoodBye的方法體\");}");
return cc.toBytecode();
} catch (NotFoundException e) {
} catch (CannotCompileException e) {
e.printStackTrace();
} catch (IOException e) {
// 忽略异常处理
}
return null;
}
/**
* 在main函数执行前,执行的函数
*
* @param options
* @param ins
*/
public static void premain(String options, Instrumentation ins) {
// 注册我自己的字节码转换器
ins.addTransformer(new AopTransformer());
}
}
1 package com.test; 2 3 public class HelloTest { 4 public void sayhello() { 5 System.out.println("HelloTest sayhello"); 6 } 7 public void sayGoodBye() { 8 System.out.println("HelloTest sayGoodBye"); 9 }10 11 public static void main(String[] args) {12 HelloTest ht = new HelloTest();13 ht.sayhello();14 ht.sayGoodBye();15 }16 }
三、執行
1. 需要告诉JVM在启动main函数之前,需要先执行premain函数。首先需要将premain函数所在的类打成jar包。并修改该jar包里的META-INF\MANIFEST.MF 文件,MANIFEST.MF 文件內容如下:
1 Manifest-Version: 1.02 Premain-Class: com.aop.AopTransformer3 Can-Redefine-Classes: true4 Can-Retransform-Classes: true5 Can-Set-Native-Method-Prefix: true
2. 將aop.jar放到同一目錄
3. 使用java命令執行main方法:
java -javaagent:.\aop.jar HelloTest
4. 執行結果比較
如果沒有添加aop執行結果如下:
HelloTest sayhelloHelloTest sayGoodBye
添加aop執行結果如下:
在HelloTest.sayhello之前執行HelloTest sayhello在HelloTest.sayhello之後執行修改HelloTest.sayGoodBye的方法體
- java 动态AOP
- Java动态代理实现AOP
- java动态代理实现aop
- java动态代理实现AOP
- java的动态代理(AOP)
- java动态代理实现AOP
- JAVA AOP之动态代理
- Java动态代理-->Spring AOP
- java动态代理与AOP
- spring aop,java动态代理
- 【Java进阶-Java动态代理与AOP】
- AOP初学者第一步:用Java动态代理实现AOP
- AOP系列之三:用Java动态代理实现AOP
- 什么是AOP系列之:用Java动态代理实现AOP
- 用Java动态代理实现AOP
- 使用Java动态代理实现AOP
- 用Java动态代理实现AOP
- 使用Java动态代理实现AOP
- Linux下Sniffer程序的实现
- webservice的header详解
- C++的重载,覆盖,隐藏
- SCOI2012——喵星人的点名(后缀数组)
- AS3 位运算
- java 动态AOP
- 剑指offer面试题20顺时针打印矩阵
- ZOJ 1868 Airline Hub(枚举)
- 回文字符串
- 最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离(链接)
- 谈web-基本
- oracle 创建序列
- 高斯图像滤波原理及其编程离散化实现方法
- 给前端开发人员的建议