参考:http://www.cnblogs.com/ctgulong/p/5011614.html
本文纯实践记录:
1、编写自定义javaagent 实现
package common;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
/**
* javaagent 导出ClassLoader load的class(包括动态生成的class)
*
* @author yangpan3
* @create 2016-07-04 18:38
*/
public class CustomAgent implements ClassFileTransformer {
// 必须包含premain 方法(虽然ClassFileTransformer并没有声明该方法)
public static void premain(String agentArgs, Instrumentation inst) {
inst.addTransformer(new CustomAgent());
}
@Override
public byte[] transform(ClassLoader loader, String className, Class
classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if (!className.startsWith("java") && !className.startsWith("sun")) {
String fileName = className.substring(className.indexOf("/") + 1) + ".class";
exportClazzToFile("D:/experiment/bytecode/export/", fileName, classfileBuffer);
System.out.println("--CustomAgent.transform() : className = " + className);
}
return classfileBuffer;
}
private void exportClazzToFile(String path, String fileName, byte[] bytes) {
File file = new File(path, fileName);
try {
File parentFile = file.getParentFile();
parentFile.mkdirs();
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file));
outputStream.write(bytes);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@echo off
javac -d . CustomAgent.java
@rem CustomAgent 打包为指定jar
jar cvfm agent.jar MANIFEST.MF commonManifest-Version: 1.0
Premain-Class: common.CustomAgent
Created-By: 1.6.0_30 (Sun Microsystems Inc.)
-javaagent:D:\experiment\bytecode\agent.jar
4、cd D:/experiment/bytecode/export/ 查看生成的动态代理class
另外,NB的JRebel 也是javaagent 实现的。