5.1 javassist基本使用
假设要使用javassist创建一个类:
package com.alibaba.dubbo.demo.test; public class Emp {
//属性
private int account;
private String name; //构造方法
public Emp() {
this.account = 1;
this.name = "xiaona";
} //getter
public int getAccount() {
return account;
} //setter
public void setAccount(int account) {
this.account = account;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} //普通方法
public void commonMethod() {
System.out.println("haha");
}
}
该类包含属性/构造方法/getter/setter/普通方法。
使用javassist来创建类:
package com.alibaba.dubbo.demo.test; import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.Modifier; import java.io.File;
import java.io.FileOutputStream; public class TestJavassitCompiler {
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass ctClass = pool.makeClass("com.alibaba.dubbo.demo.test.Emp");
//添加属性:private String name
CtField nameField = new CtField(pool.getCtClass("java.lang.String"), "name", ctClass);
nameField.setModifiers(Modifier.PRIVATE);
ctClass.addField(nameField);
//添加属性:private int account
CtField accountField = new CtField(pool.getCtClass("int"), "account", ctClass);
accountField.setModifiers(Modifier.PRIVATE);
ctClass.addField(accountField);
//getter和setter
ctClass.addMethod(CtNewMethod.getter("getName", nameField));
ctClass.addMethod(CtNewMethod.setter("setName", nameField));
ctClass.addMethod(CtNewMethod.getter("getAccount", accountField));
ctClass.addMethod(CtNewMethod.setter("setAccount", accountField));
//创建构造器
CtConstructor ctConstructor = new CtConstructor(new CtClass[] {}, ctClass);
String body = new StringBuilder("{\nthis.account = 1;\nthis.name = \"xiaona\";\n}").toString();
ctConstructor.setBody(body);
ctClass.addConstructor(ctConstructor);
//普通方法
CtMethod ctMethod = new CtMethod(CtClass.voidType, "commonMethod", new CtClass[] {}, ctClass);
ctMethod.setModifiers(Modifier.PUBLIC);
ctMethod.setBody(new StringBuilder("{\n System.out.println(\"haha\"); \n}").toString());
ctClass.addMethod(ctMethod); Class<?> clazz = ctClass.toClass();
Object obj = clazz.newInstance();
obj.getClass().getMethod("commonMethod", new Class[] {}).invoke(obj, new Object[] {});//方法调用 /**
* 将字节码输出到文件中
*/
byte[] codeByteArray = ctClass.toBytecode();
FileOutputStream fos = new FileOutputStream(new File("/Users/jigangzhao/Desktop/Emp.class"));
fos.write(codeByteArray);
fos.close();
}
}
之后可以使用javap命令来看一下/Users/jigangzhao/Desktop/Emp.class文件。
关于javassit的API请查看:
https://github.com/jboss-javassist/javassist/wiki/Tutorial-1
5.1 javassist基本使用的更多相关文章
- Javassist 通用工具之 CodeInjector
Javassist 通用工具之CodeInjector 最近在做一个APM项目,要在运行时代码修改.目前常用修改的几种工具有:ASM.BCEL.Javassist.经过对比,项目中采用了Javassi ...
- 用 javassist 来修改 class 文件
import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; public class Test { ...
- SSH整合时执行hibernate查询报错:java.lang.ClassCastException: com.ch.hibernate.Department_$$_javassist_0 cannot be cast to javassist.util.proxy
今天在整合ssh三个框架时,有一个功能,是查询所有员工信息,且员工表和部门表是多对一的映射关系,代码能正常运行到查询得到一个List集合,但在页面展示的时候,就报异常了, java.lang.Clas ...
- Java动态编程初探——Javassist
最近需要通过配置生成代码,减少重复编码和维护成本.用到了一些动态的特性,和大家分享下心得. 我们常用到的动态特性主要是反射,在运行时查找对象属性.方法,修改作用域,通过方法名称调用方法等.在线的应用不 ...
- Java javassist动态代理
package org.windwant.spring.core.proxy; import javassist.ClassPool; import javassist.CtClass; import ...
- Javassist 字节码操作
1.读写字节码 Javassist是用来处理java字节码的类库.字节码保存在二进制文件中称为类文件.每个类文件夹包括一个java类或接口. Javasssist.CtClass这个类是一个类文件的抽 ...
- 【hibernate 报错】No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer 【get和load的区别】
报错: HTTP Status 500 - Could not write content: No serializer found for class org.hibernate.proxy.poj ...
- javassist AOP
对于AOP,这个概念,不用解释,主要用途很多,我这里主要是为了后续研究如何实现APM做准备.前面研究了动态代理实现AOP,考虑到性能的问题,改用javassist直接修改直接码实现! javassis ...
- org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.
2011-08-16 13:26:58,484 [http-8080-1] ERROR [core.web.ExceptionInterceptor] - org.codehaus.jackson.m ...
- Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出 ...
随机推荐
- 用scrapy爬取京东的数据
本文目的是使用scrapy爬取京东上所有的手机数据,并将数据保存到MongoDB中. 一.项目介绍 主要目标 1.使用scrapy爬取京东上所有的手机数据 2.将爬取的数据存储到MongoDB 环境 ...
- 八. Pandas的轴
axis=0代表跨行(down),而axis=1代表跨列(across) 使用0值表示沿着每一列或行标签\索引值向下执行方法 使用1值表示沿着每一行或者列标签模向执行对应的方法 下图代表在DataFr ...
- dsu on tree题表
dsu on tree,又名树上启发式合并.重链剖分,是一类十分实用的trick,它常常可以作为一些正解的替代算法: 1.DFS序+线段树/主席树/线段树合并 2.对DFS序分块的树上莫队 3.长链剖 ...
- 利用ComponentWillReceiveProps解决异步问题
1.工作中遇到这么一个问题:有多个按钮,点击不同的按钮发送不同的请求(传的id不同)并显示弹窗,弹窗里要展示后端发送回来的数据.但是比如点击第二个按钮,弹窗里显示的仍然是第一个弹窗里的数据. 2.原因 ...
- 阿里云VPC默认网关问题
在使用VPC专用网络时,阿里云上面不用设置网关都可以工作,其实不是的,狗日的阿里云居然把默认网关设置成了253,比如设置了172.18.0.0/24时,那么它的默认网关就是172.18.0.253.
- 三星打印机SCX-4824HN全套驱动(打印/扫描)
链接: https://pan.baidu.com/s/1EUXsti4niHlYcMHMJqqnXA 密码: r91a
- Hbase总结(五)-hbase常识及habse适合什么场景
当我们对于数据结构字段不够确定或杂乱无章非常难按一个概念去进行抽取的数据适合用使用什么数据库?答案是什么,假设我们使用的传统数据库,肯定留有多余的字段.10个不行,20个,可是这个严重影响了质量. 而 ...
- C#实现路由器断开连接,更改公网ip
publicstaticvoid Disconnect() { string url ="断 线"; string uri ="http://192.168.1.1 ...
- [Winform]Media Player com组件应用中遇到的问题
摘要 最近一个项目中,需要用到在客户端全屏循环播放视频,当时考虑使用开源的播放器,但控制起来不方便,然后考虑既然都是windows系统,那么可以考虑使用微软自带的Media Player播放器.所以在 ...
- CefSharp 在同一窗口打开链接的方法
摘要 在winform中使用cefsharp的时候,我们在浏览网页的时候,想在同一个窗口打开链接,而不是创建新的窗口.可以通过下面的方法实现. 解决方案 CefSharp 中控制弹窗的接口是 ILif ...