初识javaagent技术
JavaAgent 是运行在 main方法之前的拦截器,它内定的方法名叫 premain ,也就是说先执行 premain 方法然后再执行 main 方法。
Javaagent 只要作用在class被类加载器加载之前对其加载,并且可以修改类的字节码,插入我们需要添加的字节码。从而可以达到监控类的目的。
入门demo:
1.新建一个maven项目:
首先看带premain函数的类:
package club.jiajiajia.demo.agent;
import java.lang.instrument.Instrumentation;
public class MyAgent {
/**
* 该方法在main方法之前运行,与main方法运行在同一个JVM中
* 并被同一个System ClassLoader装载
* 被统一的安全策略(security policy)和上下文(context)管理
*/
public static void premain(String agentOps, Instrumentation inst) {
System.out.println("=========premain========");
inst.addTransformer(new FirstAgent());
}
}
在FirstAgent类中修改类的字节码:
package club.jiajiajia.demo.agent;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class FirstAgent implements ClassFileTransformer {
public final String injectedClassName = "agentTest.User";
public final String methodName = "myName";
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
className = className.replace("/", ".");
if (className.equals(injectedClassName)) {
CtClass ctclass = null;
try {
ctclass = ClassPool.getDefault().get(className);// 使用全称,用于取得字节码类<使用javassist>
CtMethod ctmethod = ctclass.getDeclaredMethod(methodName);// 得到这方法实例
ctmethod.insertBefore("System.out.println(\"I'm here to make trouble.\");");
return ctclass.toBytecode();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
return null;
}
}
pom文件:
<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>test</groupId>
<artifactId>test3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.23.1-GA</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-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Premain-Class>club.jiajiajia.demo.agent.MyAgent</Premain-Class>
<!--上面一定要填写MyAgent的全类名,也可以在MANIFEST.MF文件中配置-->
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
此时我们执行:clean package 命令打包,然后得到我们需要的jar包,这个包会在后面用到->
2.新建一个测试项目:(当然也可以在上一个项目中测试)
User类:
package agentTest;
public class User {
public User(String name) {
super();
this.name = name;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
public String name;
public void myName(){
System.out.println(name);
}
}
主测试类:
package agentTest;
public class mainTest {
public static void main(String[] args) {
User u=new User("佳佳");
u.myName();
}
}
下面是重点:
在启动参数中配置javaagent:
右键项目->Run as->Run configurations
运行结果:
评论区
请写下您的评论...
猜你喜欢
blog
java调用c/c++类库(JNI技术)
java基础
2251
java调用c/c++类库(JNI技术)1.在java项目下创建native方法packagejni;/***@authorjiajia*/publicclassJniTest
blog
java动态编译技术原理分析
其他
4365
1.动态编译技术从JDK1.6开始引入了用Java代码重写的编译器接口,使得我们可以在运行时编译Java源码,然后用类加载器进行加载,让Java语言更具灵活性,能够完成许多高级的操作。2.本次要实现
ofc
计算机网络-信道复用技术
official
1304
而不用频率来表示所使用的光载波。这样就得出了波分复用这一名词。最初,人们只能在一根光纤上复用两路光载波信号。这种复用方式称为波分复用WDM。随着技术的发展,在一根光纤上复用的光载波信号的路数越来越多
weblog
1328
级java攻城尸,熟练使用各种框架,并知道它们实现的原理。jvm虚拟机原理、调优,懂得jvm能让你写出性能更好的代码;池技术,什么对象池,连接池,线程池...:;java反射技术,写框架必备的技术,但是
nginx,前端,java基础
1998
基于javanio+netty+websocket+protobuf+javascript等技术实现前后端高性能实时数据传输的demo模型。 github地址:https
official
1451
基于javanio+netty+websocket+protobuf+javascript等技术实现前后端高性能实时数据传输的demo模型。 github地址:https
spring/springmvc
6012
springmvc启动时从数据库中初始化系统常量设计的目标是,把项目的系统常量配置,放在数据库中,在项目初始化时从项目中获取配置信息,利用反射技术,把key-value对应的值自动封装进配置类。1
blog
jvm内存模型分析-类和类加载器
java虚拟机(jvm)
5768
模块称为“类加载器”。类加载器可以说是Java语言的一项创新,也是Java语言流行的重要原因之一,它最初是为了满足JavaApPlet的需求而开发出来的。虽然目前JavaApplet技术基本上已经“死掉
最新发表
归档
2018-11
12
2018-12
33
2019-01
28
2019-02
28
2019-03
32
2019-04
27
2019-05
33
2019-06
6
2019-07
12
2019-08
12
2019-09
21
2019-10
8
2019-11
15
2019-12
25
2020-01
9
2020-02
5
2020-03
16
2020-04
4
2020-06
1
2020-07
7
2020-08
13
2020-09
9
2020-10
5
2020-12
3
2021-01
1
2021-02
5
2021-03
7
2021-04
4
2021-05
4
2021-06
1
2021-07
7
2021-08
2
2021-09
8
2021-10
9
2021-11
16
2021-12
14
2022-01
7
2022-05
1
2022-08
3
2022-09
2
2022-10
2
2022-12
5
2023-01
3
2023-02
1
2023-03
4
2023-04
2
2023-06
3
2023-07
4
2023-08
1
2023-10
1
2024-02
1
2024-03
1
2024-04
1
2024-08
1
标签
算法基础
linux
前端
c++
数据结构
框架
数据库
计算机基础
储备知识
java基础
ASM
其他
深入理解java虚拟机
nginx
git
消息中间件
搜索
maven
redis
docker
dubbo
vue
导入导出
软件使用
idea插件
协议
无聊的知识
jenkins
springboot
mqtt协议
keepalived
minio
mysql
ensp
网络基础
xxl-job
rabbitmq
haproxy
srs
音视频
webrtc
javascript
加密算法
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。