????java.lang.Instrument?????? JDK5???????????????????????????????????????? ??????????? ???main?????????? ??????????????????java????????????????????? ????????????JVM? ?????ClassFileTransformer??transform?????????????????????????????AOP??????????? ??????????????CGLIB???????AOP??????????????????????????????? ??
??????1?? ???? (agent) ???????main???????????????? (interceptor)???????main??????????????agent????? agent??????????main?????? ????JVM ?????У????? ????system classloader ?????????? ??????? (security policy) ?? ?????? (context) ??????? ?????agent??????????е??????????????????????????????????java agent?????????????????д???java agent? ???????premain?????????  public static void premain(String agentArgs?? Instrumentation inst) JDK 6 ???????????????????premain????壬??????????????????premain???壺  public static void premain(String agentArgs)
??????2??Agent ???????jar???????????? META-INF/MAINIFEST.MF ????????? Premain-Class ???????? ?????????MANIFEST.MF???????
????Manifest-Version: 1.0 Premain-Class:MyAgent1 Created-By:1.6.0_06
???????? MANIFEST.MF ???????jar???С???????agent jar?????Manifest Attributes?嵥??  Premain-Class ???  JVM ???????????? ?????????????????????????? premain ??????????? JVM ??????????????????????????????????????????????? JVM ???????????????????????????????????·????  Agent-Class ????????? VM ?????? ???????????????? ???????????????????? ?????? agentmain ???????? ???????????????????????????????????? ??????????????????????????·?? ??  Boot-Class-Path ?????????????????????·???б??·????????????????????????? JAR ?? zip ????????? ??????????????????????????????????????????Щ·?? ?????г??????????·?????б??е?·??????????????????·????÷?? URI ??·??????????????·????б???????“/”??????????·????????????·???????·????????? JAR ?????·?????????????????????·??????????·??????????????? VM ?????????????????????????? JAR ?????·?????????????????  Can-Redefine-Classes ???????true ?? false?????Сд???????????????????????????true ????????????? false???????????????????? false??  Can-Retransform-Classes ???????true ?? false?????Сд????????????????????????????true ????????????? false???????????????????? false??  Can-Set-Native-Method-Prefix ???????true ?? false?????Сд???????????????????????????????????true ????????????? false???????????????????? false??
??????3?????е???ЩAgent??jar????????????????????classpath?С??????????????????????classpath?????????????classpath?????
??????4?????java??????-javaagent???????????????????????????????????????java agent?????е?java agent??????????????С? ???磺
????java -javaagent:MyAgent1.jar -javaagent:MyAgent2.jar -jar MyProgram.jar
????????MyProgram.jar?????main??????MyProgram?С?MyAgent1.jar?? MyAgent2.jar?? ??2??jar?????????premain????????MyAgent1?? MyAgent2 ??????е?????????
????MyAgent1.premain -> MyAgent2.premain -> MyProgram.main
??????5??????????main????????premain???????е?????磺
????java -javaagent:MyAgent1.jar -jar MyProgram.jar -javaagent:MyAgent2.jar
????MyAgent2 ????????MyProgram.jar???棬????MyAgent2??premain????????У???????е????????
????MyAgent1.premain -> MyProgram.main
??????6??????java agent ??????????????????????????????premain?е?agentArgs?????agentArgs?????java option?ж????????磺
????java -javaagent:MyAgent2.jar=thisIsAgentArgs -jar MyProgram.jar
????MyAgent2??premain???????agentArgs???????”thisIsAgentArgs” ????????????????
??????7???????е?Instrumentation??????????е?Instrumentation inst?????????????ClassFileTransformer???????class???????????????Transformer?????transform????????÷????????????????е????????????????????????????????????????????磺 дagent?? ??
package org.toy;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.ClassFileTransformer;
public class PerfMonAgent {
private static Instrumentation inst = null;
/**
* This method is called before the application’s main-method is called??
* when this agent is specified to the Java VM.
**/
public static void premain(String agentArgs?? Instrumentation _inst) {
System.out.println("PerfMonAgent.premain() was called.");
// Initialize the static variables we use to track information.
inst = _inst;
// Set up the class-file transformer.
ClassFileTransformer trans = new PerfMonXformer();
System.out.println("Adding a PerfMonXformer instance to the JVM.");
inst.addTransformer(trans);
}
}
????дClassFileTransformer?? ??
package org.toy;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtBehavior;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.expr.ExprEditor;
import javassist.expr.MethodCall;
public class PerfMonXformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader?? String className?? Class<?> classBeingRedefined?? ProtectionDomain protectionDomain?? byte[] classfileBuffer) throws IllegalClassFormatException {
byte[] transformed = null;
System.out.println("Transforming " + className);
ClassPool pool = ClassPool.getDefault();
CtClass cl = null;
try {
cl = pool.makeClass(new java.io.ByteArrayInputStream(
classfileBuffer));
if (cl.isInterface() == false) {
CtBehavior[] methods = cl.getDeclaredBehaviors();
for (int i = 0; i < methods.length; i++) {
if (methods[i].isEmpty() == false) {
doMethod(methods[i]);
}
}
transformed = cl.toBytecode();
}
} catch (Exception e) {
System.err.println("Could not instrument  " + className
+ "??  exception : " + e.getMessage());
} finally {
if (cl != null) {
cl.detach();
}
}
return transformed;
}
private void doMethod(CtBehavior method) throws NotFoundException??
CannotCompileException {
// method.insertBefore("long stime = System.nanoTime();");
// method.insertAfter("System.out.println("leave "+method.getName()+" and time:"+(System.nanoTime()-stime));");
method.instrument(new ExprEditor() {
public void edit(MethodCall m) throws CannotCompileException {
m.replace("{ long stime = System.nanoTime(); $_ = $proceed($$); System.out.println(""
+ m.getClassName()+"."+m.getMethodName()
+ ":"+(System.nanoTime()-stime));}");
}
});
}
}
????????????????agent????????jvm????????????ü????????? PerfMonAgent.premain?????PerfMonAgent.premain?????????????????ClassFileTransforme?? PerfMonXformer???????inst.addTransformer(trans)????PerfMonXformer?????????Instrumentation???????jvm??????????? ????е?????????? ?? PerfMonXformer.transform??????????????????п???????????????е????棬????????????????????jboss??javassist???????????????????jboss??javassist???????????????????????????
???????????????????????????????????????????????м?????long stime = System.nanoTime();?????????????????System.out.println(“methodClassName.methodName:”+(System.nanoTime()-stime));