Java Agent 概念及实操

本文详细介绍了Java Agent的概念,包括在main函数运行前后如何加载Agent,重点讲解了main函数运行前的加载方式,如使用ByteBuddy进行操作。此外,文章还探讨了动态修改类的方法,注解类拦截的实现,以及如何创建一个简单的Arthas替代方案。
摘要由CSDN通过智能技术生成

0、基本概念

class文件随着虚拟机启动的时候,会经过premain方法,premain方法中定义了transform,这个premain在虚拟机启动的时候会被执行一次,然后通过transform方法对类进行了修饰,就好像被穿了一件衣服,class加载的时候注入了transform中的内容,以后每次class执行的时候就会走一次transform里面的东西,就好下你给之前给你穿了一个衣服,以后每次看你你都穿着这个衣服。

  retransformClasses是因为agent虽然嵌入了,但是在虚拟机启动的时候,某些类比如thread,在javaagent启动之前就已经加载到了内存,javaagent也是类,在javaagent加载之前虚拟机需要加载一些必须的类来保证我的javaagent的运行,比如说thread,这个时候thread就没有被”穿上衣服“,即没有被transform修饰,也就不能被javaagent监控到,这个时候就需要retransformClasses重新加载,注意retransformClasses会让没有被”穿上衣服的类”穿上衣服“

   redefineClasses也是重新加载一次,但是这里注意并没有给类”穿衣服“,即通过这种方法加载的时候,类不会经过transform方法。这个方法的作用类似于,原来给类”穿上了衣服“,通过这个方法可以给这个类”脱了衣服“

0.1、规则

  • 添加多个transformer时,调用retransformClasses,则最后的transformer生效

  •  添加transformer且retransformClasses之后,再添加transformer且retransformClasses,则后  面添加的transformer生效

 

  •  添加两个transformer且都retransformClasses之后,删除最后添加的transformer,然后再retransformClasses,则第一个生效

 

1、main函数运行前加载

public static void premain(String agentArgs, Instrumentation inst) 
public static void premain(String agentArgs)
 

1.1 使用方式

ClassFileTransformer transformer = new ClassFileTransformer() {
			@Override
			public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
					ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
				System.out.println("premain load Class:" + className);
				return classfileBuffer;
			}
		};

注意:

 1.2 通过bytebuddy使用

public class DemoAgent {

    public static void premain(String arg, Instrumentation instrumentation) {
    	System.out.println("agent拦截开始");
    	Transformer transformer = new AgentBuilder.Transformer() {
			@Override
			public Builder<?> transform(Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader,
					JavaModule module) {
				 return builder.method(ElementMatchers.named("toString"))
	                      .intercept(MethodDelegation.to(MethodCostTime.class));
			}
		};
		
		AgentBuilder.Listener listener = new AgentBuilder.Listener() {

			@Override
			public void onDiscovery(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {
			}

			@Override
			public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module,
					boolean loaded, DynamicType dynamicType) {
				System.out.println(dynamicType.getTypeDescription().getActualName());
			}

			@Override
			public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module,
					boolean loaded) {
				
			}

			@Override
			public void onError(String typeName, ClassLoader classLoader, JavaModule module, b
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值