public interface ClassFileTransformer
请注意, The Java™ Virtual Machine Specification第3.1节中定义的术语类文件用于表示类文件格式的字节序列,无论它们是否位于文件中。
Modifier and Type | Method and Description |
---|---|
byte[] |
transform(ClassLoader loader, String className, 类<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer)
该方法的实现可以转换提供的类文件并返回一个新的替换类文件。
|
byte[] transform(ClassLoader loader, String className, 类<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException
有两种变压器,由canRetransform
参数确定 : Instrumentation.addTransformer(ClassFileTransformer,boolean)
:
canRetransform
为真 canRetransform
作为虚假或添加Instrumentation.addTransformer(ClassFileTransformer)
一旦变压器已经注册了addTransformer
,变压器将被要求每一个新的类定义和每个类重新定义。 每个类重新转换也将调用具有转换能力的变换器。 新的类定义的请求是使用ClassLoader.defineClass
或其本机等价物。 类重新定义的请求是用Instrumentation.redefineClasses
或其本机等价物进行的。 类重新发送的请求是用Instrumentation.retransformClasses
或其本机等价物进行的。 在处理请求之前,在验证或应用类文件字节之前调用变压器。 当有多个变压器时,通过链接transform
呼叫组成transform
。 也就是说,通过一次调用transform
返回的字节数组成为下一次调用的输入(通过classfileBuffer
参数)。
转换按以下顺序应用:
对于重新形成,不调用不可转换的变换器,而是重新使用先前转换的结果。 在所有其他情况下,调用此方法。 在这些分组中的每一个中,变压器按照登记的顺序进行调用。 本机变压器由Java虚拟机工具接口中的ClassFileLoadHook
事件提供)。
第一个变压器的输入(通过classfileBuffer
参数)为:
ClassLoader.defineClass
definitions.getDefinitionClassFile()
其中definitions
是Instrumentation.redefineClasses
的参数 Instrumentation.retransformClasses
如果实现方法确定不需要转换,则应返回null
。 否则,它应该创建一个新的byte[]
数组,将输入classfileBuffer
复制到所有需要的转换中,并返回新的数组。 输入classfileBuffer
不得修改。
在重新定义和重新定义的情况下,变压器必须支持重新定义语义:如果在初始定义期间变换器变化的类稍后被重新定义或重新定义,变压器必须确保第二类输出类文件是第一个输出的合法重新定义类文件。
如果变压器引发异常(它没有捕获),则后续的变压器仍将被调用,并且还将尝试加载,重新定义或重新转换。 因此,抛出异常具有为返回相同的效果null
。 为了防止在变压器代码中生成未经检查的异常时出现意外行为,变压器可以捕获Throwable
。 如果变压器认为classFileBuffer
不是有效格式化的类文件,那么它应该抛出一个IllegalClassFormatException
; 而这与返回null具有相同的效果。 它有助于格式化破坏的日志记录或调试。
loader
- 要转换的类的定义加载器,如果引导加载程序可以是
null
className
- Java虚拟机规范中定义的完全限定类和接口名称的内部形式的类的名称。
例如, "java/util/List"
。
classBeingRedefined
- 如果这是由重新定义或重新转换触发的,则重新定义或重新转换类;
如果这是一个类加载, null
protectionDomain
- 定义或重新定义类的保护域
classfileBuffer
- 类文件格式的输入字节缓冲区 - 不能修改
null
被执行,如果没有变换。
IllegalClassFormatException
- 如果输入不代表格式良好的类文件
Instrumentation.redefineClasses(java.lang.instrument.ClassDefinition...)