- Java SE6文档中是这样介绍这个包的:提供允许 Java 编程语言代理检测运行在 JVM 上的程序的服务.目前学习看来该包是用于在JVM级别实现AOP的操作。
- 接口主要分为ClassFileTransformer和Instrumentation,
(1)对于Instrumentation,该类提供了检测Java编程语言代码所需的服务。addTransformer(ClassFileTransformer transformer)方法将自定义的实现ClassFileTransformer接口的类加入到AOP机制中。接口ClassFileTransformer中定义了transform方法,返回值是byte[]数组,实现类干的活实际上是将目标类文件转换成字节码数组。
redefineClasses(ClassDefinition… definitions)也可以实现类之间的转换,传参是一个ClassDefinition集合,ClassDefinition类包含属性mClass(待转换的类Class)和mClassFile(转换后的类的字节码数组)
两种方法在premain中实现代码:
(一)
public class Premain {
public static void premain(String agentArgs,Instrumentation inst)
throws ClassNotFoundException,UnmodifiableClassException{
ClassDefinition def = new ClassDefinition(ClassFileTransformerImpl.class,ClassFileTransformerImpl
.getBytesFromFile(ClassFileTransformerImpl.DESTCLASS));
inst.redefineClasses(new ClassDefinition[] { def });
System.out.println("success");
}
}
(二)
public class Premain {
public static void premain(String agentArgs,Instrumentation inst)
throws ClassNotFoundException,UnmodifiableClassException{
inst.addTransformer(new ClassFileTransformerImpl());
}
}
(2)接口ClassFileTransformer源码
public interface ClassFileTransformer {
byte[] transform( ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer)
throws IllegalClassFormatException;
}
3:实现AOP可以在主程序main函数之前或之后执行,分别是Premain-Class的premain 方法,Agent-Class的agentmain 方法,这两者都要去jar包中META-INF文件夹下的MANIFEST.MF文件中配置下。
Manifest-Version: 1.0
Implementation-Title: springboot-002
Implementation-Version: 0.0.1-SNAPSHOT
Start-Class: com.kane.springboot002.Springboot002Application
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.1.5.RELEASE
Created-By: Maven Archiver 3.4.0
Main-Class: org.springframework.boot.loader.JarLauncher
Agent-Class: com.kane.springboot002.proxy.AgentMain
Premain-Class: com.kane.springboot002.proxy.Premain
4:特殊的jar包启动方式;
java -javaagent:jar 文件的位置 [= 传入 premain 的参数 ]