Javaagent。为何

Javaagent。为何,java,bytecode,javaagents,Java,Bytecode,Javaagents,当我试图找到使用Javaagent的示例时,在大多数情况下,它们都是使用字节码的示例。这些示例使用第三方库,如Javaassist 据我所知,Java中没有使用字节码的标准方法,在任何情况下,您都必须求助于库 因此,在调用defineClass()之前,我尝试在自己的自定义类加载器中使用这些库。当然,它运行得非常好。我可以用同样的方法更改字节码,就像我使用ClassFileTransformer的transform()方法一样 我是否正确地理解了javaagents还有另一个有用的特性,这又是它

当我试图找到使用Javaagent的示例时,在大多数情况下,它们都是使用字节码的示例。这些示例使用第三方库,如Javaassist

据我所知,Java中没有使用字节码的标准方法,在任何情况下,您都必须求助于库

因此,在调用
defineClass()
之前,我尝试在自己的自定义类加载器中使用这些库。当然,它运行得非常好。我可以用同样的方法更改字节码,就像我使用
ClassFileTransformer
transform()
方法一样


我是否正确地理解了javaagents还有另一个有用的特性,这又是它们的主要特性?因为,首先,javaagent为您提供了一个
Instrumentation
对象,Java规范说
instrument
包主要用于处理字节码。但是,如果我能实现自己的类加载器(早在引入
instrument
包之前我就可以做这件事),为什么我需要这样做呢?

Instrumentation API可以在运行时使用,而无需触及代码或编译的字节码。您可以为每个已编译的java程序插入指令(即使没有代码)。

我认为使用javaagent是不同的,因为它不是应用程序的一部分。您可以编写一个分析代理,并将其用于任何应用程序。

不要混淆JavaAgent和工具。Java代理可以使用插装,但不必这样。它可以使用Java平台提供的所有其他功能。不使用检测的代理的典型示例是JMX代理。看看像
JVisualVM
这样的工具提供了什么。它的大部分功能(探查器除外)都是通过JMX代理提供的,而不使用检测

顺便说一句,关于你关于插装和类装入器之间的区别的问题。自定义类加载器无法更改通过引导类加载器加载的类,如
java.lang.Object
(尽管在这样做之前您应该三思而后行)。此外,您的自定义类加载器必须实现原始类加载器语义才能工作。否则,例如,如果您尝试使用委托拦截加载,则当JVM尝试解析依赖项时,您的类加载器将丢失加载的所有类。并且由应用程序创建的另一个
ClassLoader
加载的所有类(例如,由RMI)都不会由您的自定义类加载程序处理


因此,插装添加了一种独立于类的
类加载器
来处理类的方法,并且(可选地)允许在加载后根据需要更改它们。

您能举个例子吗?我很抱歉,但本文中它们所做的只是将字节码转换用于ASM。classloaderOK也可以这样做,不同的例子是:编写一个分析器,可以统计java应用程序加载/使用的类的数量。然后使用它来分析,比如说ApacheTomcatWebServer。你怎么能用自定义类加载器来实现这一点呢?我不得不同意你的看法)我不可能只用自定义类加载器来实现这一点。这很明智。但据我所知,例如Mockito使用javaagent来操作字节码。Mockito将javaagent附加到JVM。但是如果这是他们的javaagent的唯一目的,他们可以简单地使用自己的类加载器。也许我不明白=)我认为Mockito在运行时动态构建代理,就像SpringAOP一样,尽管这只是我的猜测