使用javaassist在内存中动态生成类

【博文总目录>>>】|【项目源码>>>】

Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态”AOP”框架。

下面我们来学习如何使用javaassist

package wjc.javaassist;

import javassist.*;

import java.lang.reflect.Method;
import java.net.URLDecoder;

/**
 * <pre>
 * 测试javaAssist对java字节码文件进行直接操作
 * </pre>
 * Author: 王俊超
 * Date: 2018-02-21 22:21
 * Blog: http://blog.csdn.net/derrantcm
 * Github: https://github.com/wang-jun-chao
 * All Rights Reserved !!!
 */
public class ClassGeneration {
    public static void main(String[] args) {
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.makeClass("wjc.javaassist.bean.Boss");

        try {
            CtField f1 = CtField.make("private int id;", cc);
            CtField f2 = CtField.make("private String name;", cc);
            CtField f3 = CtField.make("private int age;", cc);

            cc.addField(f1);
            cc.addField(f2);
            cc.addField(f3);

            CtMethod m1 = CtMethod.make("public int getId(){return id;}", cc);
            CtMethod m2 = CtMethod.make("public void setId(int id){$0.id=$1;}", cc);
            cc.addMethod(m1);
            cc.addMethod(m2);

            CtMethod m3 = CtMethod.make("public String getName(){return name;}", cc);
            CtMethod m4 = CtMethod.make("public void setName(String name){$0.name=$1;}", cc);
            cc.addMethod(m3);
            cc.addMethod(m4);


            // 无参构造构造函数
            CtConstructor constructor1 = new CtConstructor(new CtClass[]{}, cc);
            constructor1.setBody("{$0.id=1; $0.name=\"wjc\"; $0.age=20;}");
            cc.addConstructor(constructor1);


            // 有参构造函数
            CtConstructor constructor2 = new CtConstructor(new CtClass[]{CtClass.intType, pool.get("java.lang.String"), CtClass.intType}, cc);
            constructor2.setBody("{$0.id=$1;$0.name=$2;$0.age=$3;}");
            cc.addConstructor(constructor2);



            // 取当前应用运行的根路径
            String path = ClassGeneration.class.getClassLoader().getResource("").getPath();
            path = path.contains(":") ? path.substring(1) : path;
            path = URLDecoder.decode(path, "utf-8");

            // 类生成到根路径下
            cc.writeFile(path);

            // 通过反射创建无参的实例,并调获取em方法
            //为了防止编译器报错,先用o声明,并一直使用
            Object o = Class.forName("wjc.javaassist.bean.Boss").newInstance();
            Method getter = o.getClass().getMethod("getName");
            System.out.println(getter.invoke(o));

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

运行结果:

这里写图片描述

生成的类
这里写图片描述

发布了534 篇原创文章 · 获赞 1126 · 访问量 162万+
展开阅读全文

javassist一个很奇怪的问题

08-20

采用javassist来将一个类中的field改变类型。待改变的类代码如下: [code="java"]public class JassistTest { @Autowired private StpService stpService; public void doit(Long userid){ PeakSeasonMainResponse res = stpService.getPeakOverView(userid); System.out.println(stpService.getClass().getName()); System.out.println("hello" + res); } }[/code] 进行改变操作的类如下: [code="java"]public class TestMain { public TestMain(){ } public static void main(String[] args) throws Exception{ ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.get("JassistTest"); CtField f = cc.getDeclaredField("stpService"); cc.removeField(f); cc.addField(CtField.make("private Proxy stpService;", cc)); cc.writeFile("D:\\DevProgram\\eclipse-jee-kepler-R-win32\\workspace\\stable\\fc-deimos\\target\\test-classes"); JassistTest test = new JassistTest(); test.doit(7060L); } } [/code] class文件生成后,我用反编译工具查看,Javassist已经变为如下: [code="java"]public class JassistTest { private Proxy stpService; public void doit(Long userid) { PeakSeasonMainResponse res = this.stpService.getPeakOverView(userid); System.out.println(this.stpService.getClass().getName()); System.out.println("hello" + res); } }[/code] 但当我执行TestMain.java文件中的test.doit()方法时,还是报异常了。 [code="java"]Exception in thread "main" java.lang.NoSuchFieldError: stpService at JassistTest.doit(JassistTest.java:13) at TestMain.main(TestMain.java:33) [/code] 实在搞不懂,请教大家 问答

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

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览