美文网首页
JAVAssist打印被调用方法的名称

JAVAssist打印被调用方法的名称

作者: ShrJanLan | 来源:发表于2024-04-19 23:32 被阅读0次
    编写JavassistMethodPrinter.java
    package com.shrjanlan.javassist;
    
    import javassist.ClassPool;
    import javassist.CtClass;
    import javassist.CtMethod;
    import java.io.ByteArrayInputStream;
    import java.lang.instrument.ClassFileTransformer;
    import java.lang.instrument.IllegalClassFormatException;
    import java.lang.instrument.Instrumentation;
    import java.security.ProtectionDomain;
    
    public class JavassistMethodPrinter {
    
        public static void premain(String agentArgs, Instrumentation inst) {
            inst.addTransformer(new ClassFileTransformer() {
                @Override
                public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
                    if (className != null && !className.startsWith("java/")) { // 替换为要监控的类的名称
                        try {
                            ClassPool pool = ClassPool.getDefault();
                            CtClass ctClass = pool.makeClass(new ByteArrayInputStream(classfileBuffer));
                            CtMethod[] declaredMethods = ctClass.getDeclaredMethods();
                            for (CtMethod method : declaredMethods) {
                                //if (!Modifier.isStatic(method.getModifiers())) { // 排除静态方法
                                if (method.getMethodInfo().getCodeAttribute() != null) { //检查是否有方法体
                                    String newClassName = className.replace("/", ".");
                                    String methodName = method.getName();
                                    method.insertBefore("System.out.println(\"JAVAssist=>" + newClassName + ":" + methodName + "\");");
                                }
                            }
                            ctClass.writeFile();
                            return ctClass.toBytecode();
                        } catch (Exception e) {
                            e.printStackTrace();
                            String errorMessage = e.getMessage();
                            if (errorMessage == null || errorMessage.isEmpty()) {
                                errorMessage = e.toString();
                            }
                            System.out.println("JAVAssist=errorMessage=>"+errorMessage);
                        }
                    }
                    return null;
                }
            });
        }
    }
    
    编辑清单文件MANIFEST.MF,指定Premain-Class为JavassistMethodPrinter.java
    Manifest-Version: 1.0
    Can-Redefine-Classes: true
    Can-Retransform-Classes: true
    Premain-Class: com.shrjanlan.javassist.JavassistMethodPrinter
    
    将JavassistMethodPrinter.java和MANIFEST.MF打包成JavassistMethodPrinter.jar
    Java服务启动时指定-javaagent:JavassistMethodPrinter.jar所在路径
    执行Java方法,控制台会打印方法名

    相关文章

      网友评论

          本文标题:JAVAssist打印被调用方法的名称

          本文链接:https://www.haomeiwen.com/subject/vgguxjtx.html