您的位置:首页 > 科技 > 能源 > 无锡企业网上办事大厅_公司logo设计免费生成图片_如何做网站推广及优化_电子商务网站建设的步骤

无锡企业网上办事大厅_公司logo设计免费生成图片_如何做网站推广及优化_电子商务网站建设的步骤

2025/2/28 1:09:16 来源:https://blog.csdn.net/qq_26437925/article/details/145600712  浏览:    关键词:无锡企业网上办事大厅_公司logo设计免费生成图片_如何做网站推广及优化_电子商务网站建设的步骤
无锡企业网上办事大厅_公司logo设计免费生成图片_如何做网站推广及优化_电子商务网站建设的步骤

测试团队会做java agent的事,实现测试模拟,各种数据采集等等工作,而这些不需要开发改代码来做到,只需要挂载下agent。

目录

    • javaagent认识和例子代码
      • 例子:
      • java.lang.instrument
      • 自定义实现一个javaagent
      • agent jar测试
    • 回顾javaagent的作用
    • 项目中用到agent的例子

javaagent认识和例子代码

例子:

java -javaagent:/Users/mubi/git_workspace/common1/common-test/target/common-test-1.0-SNAPSHOT-jar-with-dependencies.jar com.test.AgentTest

在这里插入图片描述

不改变代码,而是在java命令后加入-javaagent:xx.jar实现对class的干预

java.lang.instrument

https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html

Provides services that allow Java programming language agents to instrument programs running on the JVM.

即在Java编程语言中,允许Java代理(Agents)进行代码插装(Instrumentation)的服务主要由Java Agent API提供。这个API允许开发者在运行时动态修改或增强Java应用程序的字节码,而无需修改源代码或重新编译。这对于性能监控、调试、安全增强等场景非常有用。

自定义实现一个javaagent

  • MyAgent
package com.test;import java.lang.instrument.Instrumentation;/*** @Author mubi* @Date 2025/2/11 21:45*/
public class MyAgent {/*** jvm 参数形式启动,运行此方法** @param agentArgs agentArgs 是我们启动 Java Agent 时带进来的参数,比如-javaagent:xxx.jar agentArgs* @param inst*/public static void premain(String agentArgs, Instrumentation inst) {System.out.println("premain");customLogic(inst);}/*** 动态 attach 方式启动,运行此方法** @param agentArgs* @param inst*/public static void agentmain(String agentArgs, Instrumentation inst) {System.out.println("agentmain");customLogic(inst);}/*** 打印所有已加载的类名称 修改字节码** @param inst*/private static void customLogic(Instrumentation inst) {inst.addTransformer(new MyTransformer(), true);}
}
  • 使用javaassist改变class文件
package com.test;import java.io.ByteArrayInputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;/*** javassist 官方文档:http://www.javassist.org/tutorial/tutorial.html*/
public class MyTransformer implements ClassFileTransformer {@Overridepublic byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
//        System.out.println("正在加载类:" + className);if (!"com/test/Hello".equals(className)) {return classfileBuffer;}CtClass cl = null;try {ClassPool classPool = ClassPool.getDefault();cl = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));CtMethod ctMethod = cl.getDeclaredMethod("test");System.out.println("获取方法名称:" + ctMethod.getName());// 声明本地变量ctMethod.addLocalVariable("start", CtClass.longType);ctMethod.addLocalVariable("end", CtClass.longType);ctMethod.insertBefore("System.out.println(\" 动态插入的打印语句 \");");ctMethod.insertBefore("start = System.currentTimeMillis();");// $_在Javassist中是一个特殊的变量,代表当前正在处理的类或方法中的表达式ctMethod.insertAfter("System.out.println($_);");ctMethod.insertAfter("end = System.currentTimeMillis();");// 输出耗时ctMethod.insertAfter("System.out.println((end-start) + \" ms\");");byte[] transformed = cl.toBytecode();return transformed;} catch (Exception e) {e.printStackTrace();}return classfileBuffer;}
}
  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>common1</artifactId><groupId>com.container</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>common-test</artifactId><repositories></repositories><build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>2.5.5</version><executions><execution><goals><goal>attached</goal></goals><id>make-assembly</id><phase>package</phase><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifestEntries><Premain-Class>com.test.MyAgent</Premain-Class><Agent-Class>com.test.MyAgent</Agent-Class><Can-Redefine-Classes>true</Can-Redefine-Classes><Can-Retransform-Classes>true</Can-Retransform-Classes></manifestEntries></archive></configuration></execution></executions></plugin></plugins></build><properties><spring.verson>5.1.3.RELEASE</spring.verson></properties><dependencies><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.27.0-GA</version></dependency><dependency><groupId>org.ow2.asm</groupId><artifactId>asm</artifactId><version>9.2</version></dependency><dependency><groupId>org.ow2.asm</groupId><artifactId>asm-commons</artifactId><version>9.2</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies></project>

即加入:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>2.5.5</version><executions><execution><goals><goal>attached</goal></goals><id>make-assembly</id><phase>package</phase><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifestEntries><Premain-Class>com.test.MyAgent</Premain-Class><Agent-Class>com.test.MyAgent</Agent-Class><Can-Redefine-Classes>true</Can-Redefine-Classes><Can-Retransform-Classes>true</Can-Retransform-Classes></manifestEntries></archive></configuration></execution></executions></plugin>

按照要求:

An agent JAR file may have both the Premain-Class and Agent-Class attributes present in the manifest. When the agent is started on the command-line using the -javaagent option then the Premain-Class attribute specifies the name of the agent class and the Agent-Class attribute is ignored. Similarly, if the agent is started sometime after the VM has started, then the Agent-Class attribute specifies the name of the agent class (the value of Premain-Class attribute is ignored).

一个代理 JAR 文件可能在清单中同时具有 Premain-Class 和 Agent-Class 属性。 当使用 -javaagent 选项在命令行上启动代理时,Premain-Class 属性指定代理类的名称,而 Agent-Class 属性将被忽略。 同样,如果代理在 VM 启动后的某个时间启动,则 Agent-Class 属性指定代理类的名称(忽略 Premain-Class 属性的值)

打包生成agent jar

在这里插入图片描述

agent jar测试

定义Hello类

package com.test;import java.util.concurrent.TimeUnit;/*** @Author mubi* @Date 2025/2/11 23:20*/
public class Hello {public String test() {try {TimeUnit.SECONDS.sleep(1);System.out.println("hello logic");} catch (Exception e) {}return "hello test";}
}

测试类并加上agent参数-javaagent:/Users/mubi/git_workspace/common1/common-test/target/common-test-1.0-SNAPSHOT-jar-with-dependencies.jar

在这里插入图片描述

测试输出如下:

在这里插入图片描述
即完成了代理行为。

回顾javaagent的作用

JVM启动后,JVM会执行指定Agent类的premain()方法,在premain()中可以调用Instrumentation对象的addTransformer方法注册ClassFileTransformer。当JVM加载类时会将类文件的字节数组传递给ClassFileTransformer的transform方法,在transform方法中对Class文件进行解析和修改,之后JVM就会加载转换后的Class文件。

这样实例化后执行代理了的方法就能完成,因为class文件被改过且加载好了。

在这里插入图片描述

项目中用到agent的例子

当一个入口流程开始后,可能因为不同的输入,执行了不同的链路。业务如果有扩展,那么就需要是否有执行,以及执行情况。

如下 AppProcess的entry方法 的入参不同,调用的扩展点实现也是不同,通过java agent 可以采集到信息
在这里插入图片描述

  • 主程序
package com.pro.biz;import java.util.ArrayList;
import java.util.List;public class AppProcess {/*** 扩展点*/List<StrService> strServiceList;public AppProcess() {strServiceList = new ArrayList<>();}public void setStrServiceList(){strServiceList.add(new X());strServiceList.add(new Y());}public void entry(String name) {String s = null;if (name.equals("one")) {s = strServiceList.get(0).dealStr(name);System.out.println("entry:" + s);return;}if (name.equals("all")) {for (StrService strService : strServiceList) {s = strService.dealStr(name);System.out.println("entry:" + s);}return;}}
}
  • 扩展点和实现类
    在这里插入图片描述

  • Agent类

package com.pro.agent;import java.lang.instrument.Instrumentation;/*** @Author mubi* @Date 2025/2/12 22:54*/
public class StatAgent {/*** jvm 参数形式启动,运行此方法** @param agentArgs agentArgs 是我们启动 Java Agent 时带进来的参数,比如-javaagent:xxx.jar agentArgs* @param inst*/public static void premain(String agentArgs, Instrumentation inst) {
//        System.out.println("premain");customLogic(inst);}/*** 动态 attach 方式启动,运行此方法** @param agentArgs* @param inst*/public static void agentmain(String agentArgs, Instrumentation inst) {
//        System.out.println("agentmain");customLogic(inst);}/*** 打印所有已加载的类名称 修改字节码** @param inst*/private static void customLogic(Instrumentation inst) {inst.addTransformer(new StatTransformer(), true);}
}
package com.pro.agent;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.security.ProtectionDomain;/*** @Author mubi* @Date 2025/2/12 22:55*/
public class StatTransformer implements ClassFileTransformer {@Overridepublic byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
//        if (!"com/pro/biz/AppProcess".equals(className)) {
//            return classfileBuffer;
//        }CtClass cl = null;try {ClassPool classPool = ClassPool.getDefault();cl = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));CtMethod ctMethod = null;try{ctMethod = cl.getDeclaredMethod("dealStr");}catch (Exception e){}if(ctMethod != null && !className.equals("com/pro/biz/StrService")) {
//                System.out.println("获取到方法名称:" + ctMethod.getName());
//                System.out.println(className);//                ctMethod.insertBefore("System.out.println(\"入参: \" + $1);");
//                ctMethod.insertAfter("System.out.println(\"出参: \" + $_);");ctMethod.insertAfter("com.pro.stat.StrServiceCallStats.addCallInfo($0.getClass().getName(), $1, $_);");//                StringBuilder methodBody = new StringBuilder();
//                methodBody.append("{")
//                        .append("System.out.println(\"Input: \" + $1);") // input parameter
//                        .append("$r = $proceed($$);") // proceed with the original method
                        .append("System.out.println(\"Output: \" + result);") // output
//                        .append("return $r;")
//                        .append("}");
//
//                // Modify the method
//                ctMethod.setBody(methodBody.toString());}// 插入统计代码
//            String insertBeforeCode = "{ $_ = $proceed($$); " +
//                    "StrServiceCallStats.addCallInfo($0.strServiceList.get($index).getClass().getName(), $1, $_); }";
//            entryMethod.insertBefore(insertBeforeCode);byte[] transformed = cl.toBytecode();return transformed;} catch (Exception e) {e.printStackTrace();}return classfileBuffer;}
}
  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>common1</artifactId><groupId>com.container</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>common-project</artifactId><build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>2.5.5</version><executions><execution><goals><goal>attached</goal></goals><id>make-assembly</id><phase>package</phase><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifestEntries><Premain-Class>com.pro.agent.StatAgent</Premain-Class><Agent-Class>com.pro.agent.StatAgent</Agent-Class><Can-Redefine-Classes>true</Can-Redefine-Classes><Can-Retransform-Classes>true</Can-Retransform-Classes></manifestEntries></archive></configuration></execution></executions></plugin></plugins></build><properties><spring.verson>5.1.3.RELEASE</spring.verson></properties><dependencies><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.29.0-GA</version></dependency><dependency><groupId>org.ow2.asm</groupId><artifactId>asm</artifactId><version>9.2</version></dependency><dependency><groupId>org.ow2.asm</groupId><artifactId>asm-commons</artifactId><version>9.2</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies></project>

打包后生成agent jar, 运行时加上-javaagent:/Users/mubi/git_workspace/common1/common-project/target/common-project-1.0-SNAPSHOT-jar-with-dependencies.jar

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com