Java Agents代理是什么

 更新时间:2021年09月22日 08:51:47   作者:sofia  
Java代理Agents通过提供使我们能够侵入JVM中正在运行的Java程序的服务,在最底层工作。Java的这一强大但不可思议的部分具有在错误操作时使JVM崩溃的能力。本文简要介绍了这个概念,并介绍了它的工作原理。需要的朋友可以参考下面文章的具体内容

表示Java Agents的类显然只不过是Java API库中的任何其他类。但是,让它们与众不同的是,它们遵循某种约定,这种约定使Java代码能够拦截JVM中运行的另一个应用程序。其目的只是让代理调查或修改字节码。这是一个强大但不可思议的特性,超出了Java程序通常的功能范围。在某种程度上,它可以闯入一个程序,修改字节码或造成混乱。请理解,这不是添加到Java中的新技术或功能。自JDK1.5以来,它一直是库的一部分。这意味着使用它们也有一些真正的好处。但是,在讨论它们的优点以及如何使用它们之前,让我们先看看在Java中哪里可以找到它们。

一、Java Agents 和 Instrumentation

Java agentJava Instrumentation API的一部分。检测API提供了一种修改方法字节码的机制。这可以静态和动态地完成。这意味着我们可以通过向程序中添加代码来更改程序,而不必涉及程序的实际源代码。结果可能会对应用程序的整体行为产生重大影响。

Java agentinstrumentation API位于名为 Java.lang.intrumentation 的包中。

二、Java agent的使用

Java agent可以有多种用途,如面向方面编程(AOP)、变异测试、评测等。AOP通常会在不更改代码的情况下向现有程序添加日志记录或安全性等行为。它使用Java代理来操作字节码,并将其功能与程序结合起来。监视JVM级别的参数,如对象创建、垃圾收集、线程执行等,是探查器的工作。评测工具显著地使用Java代理评测执行中程序的JVM参数。

还有许多其他情况下,Java agentinstrumentation API非常方便。

三、如何编写Java代理

实现Java agent的类必须实现一个名为

public static void premain(String agentArgs, Instrumentation inst)


此方法构成代理的入口点,就像常规Java程序的入口点是主方法一样。

JVM初始化后,调用 premain 方法;这表示代理。可以有几个这样的代理;因此,将根据JVM初始化期间指定的代理的顺序调用每个 premain 方法。如果找不到特定的 premain 方法,JVM会依次调用 premain 方法的重载版本,例如

public static void premain(String agentArgs)


代理类还可能包含JVM在agent启动后通常使用的方法,例如

public static void agentmain(String agentArgs,
   instrumentation inst)


或者,它的重载版本

public static void agentmain(String agentArgs)


这是JVM的典型例程,一旦该例程完成,就会调用 main 方法。

另一件重要的事情是,Java代理在开发期间必须在资源目录的 META-INF 文件夹中包含 MANIFEST.MF 文件。此文件包含有关包分发的元数据信息。此文件作为其JAR打包的一部分包含。 MANIFEST.MF 文件中包含的属性提供了有关为什么需要这样做的线索。这些属性如下所示:

  • Premain-class :此属性定义代理类。如果未定义此属性,JVM将中止。
  • Agent-class :它定义了在JVM启动后启动Java代理的机制。如果此属性未定义,代理将不会启动。
  • Can-Redefine-Classes :这定义了代理重新定义类的能力。该值可以是truefalse
  • Can-Retransform-Classes :这定义了代理重新传输类的能力。该值可以是truefalse
  • Can-Set-Native-Method-Prefix :这定义了代理设置本机方法前缀的能力。该值可以是truefalse
  • Boot-Class-Path :定义引导类加载程序的搜索路径列表。

一个简单的例子:

探查器工具通常通过从JVM提取信息来报告运行时Java对象的不同参数。这些参数包括关于使用检测框架的对象的内存使用等信息。

1. 这里我们使用 premain 方法创建一个代理类。

2. 传递给 premain 方法的检测实例将提供有关对象大小的信息。

3. 将代理类与 MANIFEST.MF 文件一起打包到JAR文件中。

4. 使用命令行参数将代理传递给JVM。

这是我们将在示例中使用的示例类。这没什么特别的。

package com.mano.examples;
public class Main {
   public static void greet(String msg){
      System.out.println(msg);
   }
   public static void main(String[] args){
      greet("Hello Agents");
   }
}

四、代理类

带有 premain 方法的instrumentation agent类用于检索我们需要的信息。插装接口的实现被传递给 premain 方法。我们使用由instrumentation接口定义的 getObjectSize 方法来获取运行时主对象的内存使用情况。

package com.mano.examples;
import java.lang.instrument.Instrumentation;
public class MyAgentClass {
   public static void premain(String agentArgs,
      Instrumentation inst) {
      System.out.println(inst.getObjectSize
         (new Main()))
   }
}

之后,我们必须创建 MANIFEST.MF 文件。这只是一个文本文件,我们在其中放置与代理类相关的信息。JVM将使用它来加载代理。该文件通常存储在 META-INF 目录中。

我们的示例所需的内容非常基本:

Manifest-Version: 1.0
Premain-Class: com.mano.examples.MyAgentClass

现在,编译所有Java文件以创建类文件。最后,创建JAR文件,如下所示:

jar -cmf META-INF/MANIFEST.MF myagent.jar com/mano/examples/
   MyAgentClass.class

五、部署Java Agents

创建代理后,它将作为JAR文件部署。清单文件中的属性指定将加载以启动代理的代理类。请注意,启动代理有很多方法:使用命令行、运行时或作为JAR可执行文件。我们将在这里使用命令行。

使用命令行运行Agents代理

命令行是:

java -javaagent:myagent.jar -cp . com.mano.examples.Main

这表示 premain 方法将在应用程序执行之前运行,并创建 Main 实例的大小。

结论:

仪器API所提供的功能可以进行多种创新。AOP是一个简单的例子。虽然Java代理和Java Instrumentation API在应用程序开发中不经常使用,但是关于它的全部内容的想法可以澄清Java的许多其他方面。这里给出的代码示例是初步的,只是为了说明如何创建代理。

到此这篇关于Java Agents代理是什么的文章就介绍到这了,更多相关Java Agents代理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现字符串倒序输出的四种方法汇总

    Java实现字符串倒序输出的四种方法汇总

    这篇文章主要介绍了Java实现字符串倒序输出的四种方法汇总,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • maven中添加memcached.jar的配置步骤

    maven中添加memcached.jar的配置步骤

    在Java项目中使用Maven管理依赖时,如果需要添加​​memcached.jar​​依赖,可以通过本文介绍的步骤进行配置,文章通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-12-12
  • mybatis分割字符串并循环,实现in多个参数的操作

    mybatis分割字符串并循环,实现in多个参数的操作

    这篇文章主要介绍了mybatis分割字符串并循环,实现in多个参数的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 通过案例了解静态修饰符static使用场景

    通过案例了解静态修饰符static使用场景

    这篇文章主要介绍了通过案例了解静态修饰符static使用场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Maven管理SpringBoot Profile详解

    Maven管理SpringBoot Profile详解

    这篇文章主要介绍了Maven管理SpringBoot Profile详解,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • 解决SpringMVC获取请求参数乱码问题

    解决SpringMVC获取请求参数乱码问题

    在使用SpringMVC和thymeleaf进行请求参数处理时,可能会遇到乱码问题,对于GET方法乱码,可通过修改Tomcat的server.xml文件,添加URIEncoding="UTF-8"解决,而POST方法乱码,则需在web.xml配置SpringMVC提供的过滤器
    2024-11-11
  • javaBean的基础知识及常见乱码解决方法

    javaBean的基础知识及常见乱码解决方法

    这篇文章主要介绍了javaBean的基础知识及常见乱码解决方法的相关资料,需要的朋友可以参考下
    2017-03-03
  • Java源码难点突破Lambda表达式执行原理

    Java源码难点突破Lambda表达式执行原理

    这篇文章主要为大家介绍了Java难点突破Lambda表达式执行原理分析及示例的实现源码,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-03-03
  • MybatisPlus分页排序查询字段带有下划线的坑及解决

    MybatisPlus分页排序查询字段带有下划线的坑及解决

    这篇文章主要介绍了MybatisPlus分页排序查询字段带有下划线的坑及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Springboot 多租户SaaS搭建方案

    Springboot 多租户SaaS搭建方案

    这篇文章主要介绍了Springboot 多租户SaaS方案,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06

最新评论