核心代码DEMO,仅供参考:
package com.zcm.transform.premain;
import javassist.*;
import java.io.File;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.*;
import java.util.jar.JarFile;
/**
* 检测方法的执行时间
*
* @author 周cm
* @myblog xx
* @create 2018年4月21日
*/
public class DubboTransformer extends BaseTransformer implements ClassFileTransformer {
final static String prefix = "\nlong startTime = System.currentTimeMillis();\n";
final static String postfix = "\nlong endTime = System.currentTimeMillis();\n";
// 被处理的方法列表
final static Map<String, List<String>> methodMap = new HashMap<String, List<String>>();
static boolean hasIn = false;
ClassLoader dubboTransformClassLoader;
String agentOps;
Instrumentation inst;
public DubboTransformer() {
add("com.zcm.service.impl.IDogImpl",ROUTER);
add("com.alibaba.dubbo.config.ReferenceConfig", ROUTER);
add("com.alibaba.dubbo.config.ApplicationConfig", ROUTER);
//add("com.alibaba.dubbo.config.ConsumerConfig", ROUTER);
add("com.alibaba.dubbo.config.ServiceConfig", DYNAMIC_GROUP);
dubboTransformClassLoader = DubboTransformer.class.getClassLoader();
}
public DubboTransformer(String agentOps, Instrumentation inst){
this();
this.agentOps = agentOps;
this.inst = inst;
try {
String filePath = "C:\\Users\\ody\\workspace\\jim-framework-master\\full-link-log\\web\\target\\web-1.2-SNAPSHOT\\WEB-INF\\lib\\dubbo-2.6.0.jar";
String filePath1 = "C:\\Users\\ody\\workspace\\jim-framework-master\\full-link-log\\web\\target\\web-1.2-SNAPSHOT\\WEB-INF\\lib\\javassist-3.20.0-GA.jar";
JarFile jarFile = new JarFile(filePath);
//inst.appendToBootstrapClassLoaderSearch(jarFile);
//inst.appendToSystemClassLoaderSearch(jarFile);
//inst.appendToSystemClassLoaderSearch(new JarFile(filePath1));
//SimpleLoadAJar.addJar(filePath);
//SimpleLoadAJar.addJar(filePath1);
} catch (IOException e) {
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
private void add(String clazzString,String method) {
methodMap.put(clazzString, Arrays.asList(method));
}
public static final String DYNAMIC_GROUP = "dynamicGroup";
public static final String ROUTER = "router";
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
className = className.replace("/", ".");
if (methodMap.containsKey(className)) {// 判断加载的class的包路径是不是需要监控的类
CtClass ctclass = null;
ensureAdditionalJar( loader);
try {
ctclass = ClassPool.getDefault().get(className);// 使用全称,用于取得字节码类<使用javassist>
List<String> methods = methodMap.get(className);
if (methods != null){
for (String method : methods){
addAdditionMethod(ctclass,method,method);
}
}
return ctclass.toBytecode();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
return null;
}
private void ensureAdditionalJar( ClassLoader classLoader) {
if ( !hasIn ){
hasIn = true;
}else {
return ;
}
if (classLoader == dubboTransformClassLoader){
return;
}
for (String className : Arrays.asList("com/alibaba/dubbo/config/ApplicationConfig.class","javassist/ClassPool.class")){
URL url = classLoader.getResource(className);
if ( url == null){
System.err.println(" can not found dubbo.jar in " + classLoader);
continue;
}
System.out.println(url);
inst.appendToSystemClassLoaderSearch(convertUrl2jarFile(url));
}
}
private JarFile convertUrl2jarFile(URL url) {
String filePath = url.getPath();
try {
int index = filePath.indexOf("!");
if (index > -1){
filePath = filePath.substring(5,index);
return new JarFile(filePath);
}
File file = new File( url.toURI());
System.out.println("..");
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private CtClass addAdditionMethod(CtClass ctClass , String methodKey , String systemPropertyKey){
String methodName = "get" + methodKey.substring(0,1).toUpperCase() + methodKey.substring(1);
CtMethod method = null;
try {
CtMethod ctmethod = ctClass.getDeclaredMethod(methodName);
if (ctmethod != null){
System.err.println(ctClass + " has got " + method);
return ctClass ;
}
}catch (Exception e){
// no method
}
try {
method = new CtMethod(ClassPool.getDefault().get("java.lang.String"), methodName, new CtClass[]{}, ctClass);
method.setModifiers(Modifier.PUBLIC);
String methodContent = "{return System.getProperty(\"" + systemPropertyKey + "\");}";
//methodContent = "{return System.getProperty(\"hah\");}";
method.setBody(methodContent);
ctClass.addMethod(method);
}catch (Exception e){
System.err.println(" agent dynamic add method error");
e.printStackTrace();
}
return ctClass;
}
}