javaagent

一、javaagent可以做什么?
此时你还坚定的认为Java程序最先执行的是main方法?今天教你如何打破平凡!造就不平凡的你!javaagent帮你做到,当你的主程序运行之前或者运行时都可以运行部分你的其他逻辑!
1、创建java maven项目
2、在resources下创建META-INF/MANIFEST.MF文件,内容为:

Manifest-Version: 1.0
Created-By: hi.zhaojinwei.work
Premain-Class: com.zjw.PremainClass
Agent-Class: com.zjw.AgentClass

3、maven pom文件依赖打包插件maven-jar-plugin

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                        </manifest>
                        <manifestEntries>
                            <Premain-Class>
                                com.zjw.PremainClass
                            </Premain-Class>
                            <Agent-Class>
                                com.zjw.AgentClass
                            </Agent-Class>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

4、创建com.zjw.PremainClass和com.zjw.AgentClass类

package com.zjw;

import java.lang.instrument.Instrumentation;

public class PremainClass {

    private static Instrumentation instrumentation;

    public static void premain(String args, Instrumentation instrumentation) {
        PremainClass.instrumentation = instrumentation;
    }

    public static long getObjectSize(Object o) {
        return instrumentation.getObjectSize(o);
    }
}
package com.zjw;

import java.lang.instrument.Instrumentation;

public class AgentClass {

    public static void agentmain(String args, Instrumentation instrumentation) {
        System.out.println("agentmain args:" + args);
        Class[] initiatedClasses = instrumentation.getAllLoadedClasses();
        for (Class initiatedClass : initiatedClasses) {
            System.out.println(initiatedClass);
        }
    }
}

5、在主程序项目中依赖javaagent项目jar,并且jvm参数设置为javaagent jar包的路径:

-javaagent:/Users/zhaojinwei/Desktop/javaagent/target/javaagent-1.0.jar

6、启动主程序就可以正常调用javaagent的获取对象大小内存大小的方法了

Object o=new Object();
long objectSize = PremainClass.getObjectSize(o);
System.out.println(objectSize);

7、AgentClass 怎么执行呢?当主程序运行时新启动一个java项目调用:

    public static void main(String[] args) throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException {
        //获取本机中所有的jvm描述对象
        List<VirtualMachineDescriptor> list = VirtualMachine.list();
        AtomicReference<String> id=new AtomicReference<>();
        list.forEach(p->{
            if("com.example.demo.DemoApplication".equals(p.displayName())){
                //com.example.demo.DemoApplication为主程序的displayName,即:这里获取主程序jvm的进程id
                id.set(p.id());
            }
        });
        //将主进程id传入attach
        VirtualMachine vm = VirtualMachine.attach(id.get());
        //javaagent jar的位置和AgentClass.agentmain的参数
        vm.loadAgent("/Users/zhaojinwei/Desktop/javaagent/target/javaagent-1.0.jar","zhaojinwei1");
    }

8、运行这个新项目,会看见你的主程序执行了AgentClass.agentmain方法
注意:你的主程序一直处于运行状态AgentClass.agentmain才能正常调用,不然主程序运行结束新的项目就不能通过VirtualMachine.attach(id.get())连接不到你的主程序jvm进程,比如我们主程序可以是一个spring boot web项目

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容