java agent介绍
java agent是jvm插件或者叫做代理,她是运行在main方法之前,她内定的方法名称叫premain。
java agent 概述

接下来我们进行开发
实现premain方法
1 2 3 4 5 6 7
| package org.xxz;
public class AgentMain { public static void premain(String args, Instrumentation inst) { System.out.println('hello java agent'); } }
|
上面的这段代码就完成了java agent的第一步了
打包
这里我们使用maven的方式进行打包,请看下面的配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| <build> <finalName>java-agent</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.0.0</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> </manifest> <manifestEntries> <Premain-Class>org.xxz.AgentMain</Premain-Class> </manifestEntries> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
|
使用java agent
新建一个maven工程,打包然后运行
1
| java -jar demo.jar -javaagent:/apps/java-agent.jar
|
执行上面的运行命令后,在我们控制台输出时就会看到hello java agent的字样哦!!!
看到这里就结束了吗?没有哦,我们来看一个小例子。。。。。。。
新建maven工程
1 2 3 4 5 6 7 8 9 10 11
| java-agent --src --main --java --org.xxz --AgentMain.java --TimeInterceptor.java --TraceTime.java --resource --test --pom.xml
|
首先看看我们的pom.xml是如何配置的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| <?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"> <modelVersion>4.0.0</modelVersion>
<groupId>org.xxz</groupId> <artifactId>java-agent</artifactId> <version>1.0</version>
<properties> <bytebuddy.version>1.8.0</bytebuddy.version> <slf4j.version>1.7.25</slf4j.version> </properties>
<dependencies> <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy</artifactId> <version>${bytebuddy.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.0.0</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> </manifest> <manifestEntries> <Premain-Class>org.xxz.AgentMain</Premain-Class> </manifestEntries> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
|
这里我们使用了bytebuddy,不懂得看官可以上官方网站瞧瞧http://bytebuddy.net/
再来看看我们得AgentMain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| package org.xxz;
import net.bytebuddy.agent.builder.AgentBuilder; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.implementation.MethodDelegation; import net.bytebuddy.matcher.ElementMatchers; import net.bytebuddy.utility.JavaModule;
import java.lang.instrument.Instrumentation;
public class AgentMain {
public static void premain(String args, Instrumentation inst) {
AgentBuilder.Transformer transformer = new AgentBuilder.Transformer() { @Override public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule) { return builder .method(ElementMatchers.any()) .intercept(MethodDelegation.to(TimeInterceptor.class)); } };
AgentBuilder.Listener listener = new AgentBuilder.Listener() { @Override public void onDiscovery(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {
}
@Override public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b, DynamicType dynamicType) {
}
@Override public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b) {
}
@Override public void onError(String s, ClassLoader classLoader, JavaModule javaModule, boolean b, Throwable throwable) {
}
@Override public void onComplete(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {
} };
new AgentBuilder .Default() .type(ElementMatchers.nameStartsWith("org.xxz")) .transform(transformer) .with(listener) .installOn(inst);
}
}
|
这里我们看看我们得TimeInterceptor.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package org.xxz;
import net.bytebuddy.implementation.bind.annotation.Origin; import net.bytebuddy.implementation.bind.annotation.RuntimeType; import net.bytebuddy.implementation.bind.annotation.SuperCall;
import java.lang.reflect.Method; import java.util.concurrent.Callable;
public class TimeInterceptor {
@RuntimeType public static Object interceptor(@Origin Class clazz, @Origin Method method, @SuperCall Callable<?> callable) throws Exception {
TraceTime traceTime = method.getAnnotation(TraceTime.class);
if (traceTime == null) { return callable.call(); }
long start = System.currentTimeMillis(); try { return callable.call(); } finally { System.out.println(clazz.getSimpleName() + "#" + method.getName() + " cost " + (System.currentTimeMillis() - start) + "ms"); } }
}
|
最后就是我们得注解了TraceTime.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package org.xxz;
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface TraceTime { }
|
到这里我们得java-agent就开发完成了。。。。。是不是很简单啊。。。。
接下来,我们看看使用方式咯。。。。。
1 2 3 4 5 6 7 8 9 10 11 12
| java-agent-test --src --main --java --org.xxz --test --AgentMainTest.java --Demo.java --TraceTime.java --resource --test --pom.xml
|
依旧先看我们得pom文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <?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"> <modelVersion>4.0.0</modelVersion>
<groupId>org.xxz</groupId> <artifactId>java-agent-test</artifactId> <version>1.0</version>
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf-8</encoding> </configuration> </plugin> </plugins> </build> </project>
|
这里的pom文件上面的简单多了。
看看我们的测试类AgentMainTest.java
1 2 3 4 5 6 7 8 9 10 11
| package org.xxz.test;
public class AgentMainTest {
public static void main(String[] args) throws Exception { Demo demo = new Demo(); demo.print("agent"); } }
|
看看我们的Demo.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package org.xxz.test;
import org.xxz.TraceTime;
public class Demo {
@TraceTime public void print(String string) throws InterruptedException { Thread.sleep(100L); System.out.println("hello " + string); } }
|
这里还少了一个TraceTime.java,把上面的拷贝过来哦。。。。注意包的结构要一样哦。。。。。
上面介绍了如何命令行使用java-agent.jar,这里我们介绍如何再IDE中使用,要上图了哦。。。。。

好了,今天的文章到这里就结束了。。。
最后还来一张运行结果吧。。。。

如果您觉得文章有用或对您有帮助,欢迎通过以下方式赞助我。 ♪(^∀^●)ノ