Java二进制类型方法替换工具

配置文件:

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);
    }

}
 

发布了25 篇原创文章 · 获赞 1 · 访问量 1961
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览