配置文件:
zhaiky.properties
clazz=com.zhaiky.A #原类
oldmethod=method1 #原类中的方法
clazznewmethod=com.zhaiky.repalceBmethod2.method1 #新类方法的绝对路径
clazzpath=C://zhaiky //替换后,类存放的位置
启动的时候加参数启动com.zhaiky.ReplaceMain:
-Dconfig=D\\zhaiky.properties
源码:
package com.zhaiky;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import com.zhaiky.javassist.ClassPool;
import com.zhaiky.javassist.CtClass;
import com.zhaiky.javassist.CtMethod;
import com.zhaiky.javassist.CtNewMethod;
/**
* com.zhaiky.ReplaceMain
* -Dconfig=D:\\daima\\forboss\\javassistDemo\\src\\zhaiky.properties
* @author zhaikaiyun
*
*/
public class ReplaceMain {
public static String configpath = "/root/monitor/config.properties";
public static String clazz =null;
public static String oldmethod =null;
public static String clazznewmethod =null;
public static String clazzpath =null;
static{
configpath = System.getProperty("config");
clazz = getProperties("clazz");
oldmethod = getProperties("oldmethod");
clazznewmethod = getProperties("clazznewmethod");
clazzpath = getProperties("clazzpath");
if(configpath==null||configpath.equals("")){
throw new RuntimeException("jvm运行参数中没有-Dconfig的配置");
}
if(clazz==null||clazz.equals("")){
throw new RuntimeException(configpath+"文件中未配置clazz原类信息");
}
if(oldmethod==null||oldmethod.equals("")){
throw new RuntimeException(configpath+"文件中未配置原oldmethod方法信息");
}
if(clazznewmethod==null||clazznewmethod.equals("")){
throw new RuntimeException(configpath+"文件中未配置新clazznewmethod方法信息");
}
if(clazzpath==null||clazzpath.equals("")){
throw new RuntimeException(configpath+"文件中未配置新字节码clazz保存路径");
}
}
/**
* zhaikaiyun
*/
public static void main(String[] args) throws Exception {
// 用于取得字节码类,必须在当前的classpath中,使用全称
CtClass ctClass = ClassPool.getDefault().get(clazz);
// 需要修改的方法名称
String mname = oldmethod;
CtMethod mold = ctClass.getDeclaredMethod(mname);
String type = mold.getReturnType().getName();
// 修改原有的方法名称
String nname = mname + "$impl";
mold.setName(nname);
// 创建新的方法,复制原来的方法
CtMethod mnew = CtNewMethod.copy(mold, mname, ctClass, null);
// 主要的注入代码
StringBuffer body = new StringBuffer();
body.append("{\n;\n");
if (!"void".equals(type)) {
body.append(type + " result = ");
}
// 调用原有代码,类似于method();($$)表示所有的参数
body.append(clazznewmethod + "($$);\n");
if (!"void".equals(type)) {
body.append("\nreturn result;\n");
}
body.append("}");
// 替换新方法
mnew.setBody(body.toString());
// 增加新方法
ctClass.addMethod(mnew);
ctClass.writeFile(clazzpath);
}
public static String getProperties(String key) {
// 生成properties对象
Properties p = new Properties();
try {
// 生成文件对象
File pf = new File(configpath);
// 生成文件输入流
FileInputStream inpf = new FileInputStream(pf);
p.load(inpf);
} catch (Exception e) {
e.printStackTrace();
}
return p.getProperty(key);
}
}