标签:java javaagent methodName String 项目 bodyStr className 使用 import
相关代码参考: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
的包。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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<String, List<String>> methodMap = new HashMap<String, List<String>>(); 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<String> list = methodMap.get(className); 30 if (list == null) { 31 list = new ArrayList<String>(); 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);// 使用全称,用于取得字节码类<使用javassist> 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
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。