java的premain

ByteGalacticEcho
• 阅读 4447

特性

在类的字节码载入JVM前会调用ClassFileTransformer的transform方法,从而实现修改原类方法的功能。

原理

JVMTI(Java Virtual Machine Tool Interface)是一套本地编程接口集合,它提供了一套『代理』机制,可以支持第三方工具程序以代理的方式连接和访问 JVM,并利用 JVMTI 提供的丰富的编程接口,完成很多跟 JVM 相关的功能。

java.lang.instrument 包的实现,也就是基于这种机制的:在 Instrumentation 的实现当中,存在一个 JVMTI 的代理程序,通过调用 JVMTI 当中 Java 类相关的函数来完成 Java 类的动态操作。

Instrumentation 的最大作用就是类定义的动态改变和操作。在 Java SE 5 及其后续版本当中,开发者可以在一个普通 Java 程序(带有 main 函数的 Java 类)运行时,通过 – javaagent 参数指定一个特定的 jar 文件(包含 Instrumentation 代理)来启动 Instrumentation 的代理程序。

要素

Premain-Class

打成jar包,在jar包里面的 META-INF/MAINIFEST.MF 必须包含 Premain-Class这个属性。
如果 JVM 启动时指定了代理,那么此属性是必需的,即包含 premain 方法的类。如果该属性不存在,那么 JVM 将中止。

Agent-Class

如果实现支持 VM 启动之后某一时刻启动代理的机制,那么此属性指定代理类。 即包含 agentmain 方法的类。

Boot-Class-Path

设置引导类加载器搜索的路径列表。路径表示目录或库(在许多平台上通常作为 JAR 或 zip 库被引用)。

Can-Redefine-Classes

布尔值(true 或 false,与大小写无关)。是否能重定义此代理所需的类。true 以外的值均被视为 false。此属性是可选的,默认值为 false。

Can-Retransform-Classes

布尔值(true 或 false,与大小写无关)。是否能重转换此代理所需的类。true 以外的值均被视为 false。此属性是可选的,默认值为 false。

Can-Set-Native-Method-Prefix

布尔值(true 或 false,与大小写无关)。是否能设置此代理所需的本机方法前缀。true 以外的值均被视为 false。此属性是可选的,默认值为 false。

实例

import java.lang.instrument.Instrumentation;  
  
public class MyAgent {  
    public static void premain(String agentOps, Instrumentation inst){  
        System.out.println(agentOps);  
    }  
}  

运行

java -javaagent:myagent.jar=youragrs -jar demo.jar

docs

点赞
收藏
评论区
推荐文章
限时发布!纯手打“RocketMQ笔记”
1JVM的内存区域布局java代码的执行步骤有三点java源码文件编译器字节码文件字节码文件JVM机器码机器码系统CPU执行JVM执行的字节码需要用类加载来载入;字节码文件可以来自本地文件,可以在网络上获取,也可以实时生成。就是说你可以跳过写java代码阶段,直接生成字节码交由JVM执行其中Jav
小梁同学 小梁同学
4年前
从未有人把JVM原理讲的这么详细
JVM原理1.简述JVM是JavaVirtualMachine(Java虚拟机)的缩写,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。由一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域等组成。JVM屏蔽了与操作系统平台相关的信息,使得Java程序只需要生成在Java虚拟机上运行的目标代码(字节码),就可在多种平台上不加修改的运
Wesley13 Wesley13
3年前
java基础类库
java类库的基本介绍与用户互动运行Java程序的参数main()方法分析public修饰符:Java类由JVM调用,为了让JVM可以自由调用这个main()方法,所以使用public修饰符把这个方法暴露出来static修饰符:JVM调用这个主方法时,不会先创建该类的对象,然后通过对象来调用该主方法
待兔 待兔
4年前
Java多态实现原理
Java多态概述多态是面向对象编程语言的重要特性,它允许基类的指针或引用指向派生类的对象,而在具体访问时实现方法的动态绑定。Java对于方法调用动态绑定的实现主要依赖于方法表,但通过类引用调用(invokevirtual)和接口引用调用(invokeinterface)的实现则有所不同。类引用调用的大致过程为:Java编译器将Java源代码编译成c
Easter79 Easter79
3年前
Spring的两种代理JDK和CGLIB的区别浅谈
一、原理区别:java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以
Easter79 Easter79
3年前
Spring的Aop调用当前类的两种方法
我们知道Spring对于AOP实现有两种方法,如果类是接口实现类,则采用JDK动态代理实现AOP。如果类没有实现接口,则采用cglib生成子类做增强,以实现代理类的目的,其实运行时找到的是这个代理类,而不是原类。所以在一个代理类中调用内部的方法,是不是再走AOP逻辑的,那有什么好的方法可以解决这种问题吗?基于上面的思路有两种解决办法方法一:直接从
Stella981 Stella981
3年前
JVM入门到放弃之基本概念
1\.基本概念jvm是可运行Java代码的假想计算机,包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。jvm是运行在操作系统之上的,屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在jvm上运行的字节码,就可以在多种平台上不加修改地运行。Java语言的一个非常重要的特点就是与平台的无关性(
Wesley13 Wesley13
3年前
Java 动态代理机制分析及扩展,第 1 部分
引言Java动态代理机制的出现,使得Java开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架。通过阅读本文,读者将会对Java动态代理机制有更加深入的理解
Easter79 Easter79
3年前
Spring的两种动态代理:Jdk和Cglib 的区别和实现
一、原理区别:java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以
Wesley13 Wesley13
3年前
CAS机制与自旋锁
CAS(CompareandSwap),即比较并替换,java并发包中许多Atomic的类的底层原理都是CAS。它的功能是判断内存中某个地址的值是否为预期值,如果是就改变成新值,整个过程具有原子性。具体体现于sun.misc.Unsafe类中的native方法,调用这些native方法,JVM会帮我们实现汇编指令,这些指令是CPU的原子指令,因此
Stella981 Stella981
3年前
Dubbo之服务调用
概述Dubbo能够像调用本地服务一样调用远程服务,是依赖于Dubbo的代理机制。业务系统调用的服务方法,使用代理类,代理类里隐藏了远程通信的功能。代理对象会代理到InvokerInvocationHandler上,再调用它属性Invoker_invoke_()方法。这个Invoker是服务引用的过程中由Protocol创建的。比如
ByteGalacticEcho
ByteGalacticEcho
Lv1
等待着大雪的纷纷扬扬,把每一个梦筑成洁白的巢。
文章
6
粉丝
0
获赞
0