java javaagent_javaagent项目中使用

相关代码参考:http://blog.csdn.net/catoop/article/details/51034778

近期项目中需要对SpringMVC中的Controller方法进行拦截做预处理,才接触到javaagent,仅作记录,以防忘记。

思路:

1.声明MyTransformer类,实现ClassFileTransformer接口,该接口只有一个方法:byte[] transform(ClassLoader loader,String className,Class> classBeingRedefined,ProtectionDomain protectionDomain,byte[] classfileBuffer) throws IllegalClassFormatException;在该方法中获取指定类的指定方法,修改其字节码,达到拦截的目的;如果需要修改方法字节码,则需要引入javassist-*.*.*-GA.jar的包。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 import java.lang.instrument.ClassFileTransformer;

2 import java.lang.instrument.IllegalClassFormatException;

3 import java.security.ProtectionDomain;

4 import java.util.ArrayList;

5 import java.util.HashMap;

6 import java.util.List;

7 import java.util.Map;

8 import javassist.ClassPool;

9 import javassist.CtClass;

10 import javassist.CtMethod;

11 import javassist.CtNewMethod;

12

13 public class MyTransformer implements ClassFileTransformer {

14

15 final static String prefix = "\nlong startTime = System.currentTimeMillis();\n";

16 final static String postfix = "\nlong endTime = System.currentTimeMillis();\n";

17

18 // 被处理的方法列表

19 final static Map> methodMap = new HashMap>();

20

21 public MyTransformer() {

22 add("com.shanhy.demo.TimeTest.sayHello");

23 add("com.shanhy.demo.TimeTest.sayHello2");

24 }

25

26 private void add(String methodString) {

27 String className = methodString.substring(0, methodString.lastIndexOf("."));

28 String methodName = methodString.substring(methodString.lastIndexOf(".") + 1);

29 List list = methodMap.get(className);

30 if (list == null) {

31 list = new ArrayList();

32 methodMap.put(className, list);

33 }

34 list.add(methodName);

35 }

36

37 @Override

38 public byte[] transform(ClassLoader loader, String className, Class> classBeingRedefined,

39 ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {

40 className = className.replace("/", ".");

41 if (methodMap.containsKey(className)) {// 判断加载的class的包路径是不是需要监控的类

42 CtClass ctclass = null;

43 try {

44 ctclass = ClassPool.getDefault().get(className);// 使用全称,用于取得字节码类

45 for (String methodName : methodMap.get(className)) {

46 String outputStr = "\nSystem.out.println(\"this method " + methodName

47 + " cost:\" +(endTime - startTime) +\"ms.\");";

48 CtMethod ctmethod = ctclass.getDeclaredMethod(methodName);// 得到这方法实例

49 String newMethodName = methodName + "$old";// 新定义一个方法叫做比如sayHello$old

50 ctmethod.setName(newMethodName);// 将原来的方法名字修改

51 // 创建新的方法,复制原来的方法,名字为原来的名字

52 CtMethod newMethod = CtNewMethod.copy(ctmethod, methodName, ctclass, null);

53 // 构建新的方法体

54 StringBuilder bodyStr = new StringBuilder();

55 bodyStr.append("{");

56 bodyStr.append(prefix);

57 bodyStr.append(newMethodName + "($$);\n");// 调用原有代码,类似于method();($$)表示所有的参数

58 bodyStr.append(postfix);

59 bodyStr.append(outputStr);

60 bodyStr.append("}");

61

62 newMethod.setBody(bodyStr.toString());// 替换新方法

63 ctclass.addMethod(newMethod);// 增加新方法

64 }

65 return ctclass.toBytecode();

66 } catch (Exception e) {

67 System.out.println(e.getMessage());

68 e.printStackTrace();

69 }

70 }

71 return null;

72 }

73 }

View Code

标签:java,javaagent,methodName,String,项目,bodyStr,className,使用,import

来源: https://www.cnblogs.com/Java-Script/p/11089314.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值