Javassist学习总结

原创 2013年08月16日 11:49:08

要想将编译时不存在的类在运行时动态创建并加载,通常有两种策略:

1.      动态编译

2.      动态生成二进制字节码(.class)

对于第二种策略,实际上已经有诸多比较成熟的开源项目提供支持,如CGLib、ASM、Javassist等。这些开源项目通常都具备两方面的功能:

1.      动态创建新类或新接口的二进制字节码

2.      动态扩展现有类或接口的二进制字节码

其中,CGLib的底层基于ASM实现,是一个高效高性能的生成库;而ASM是一个轻量级的类库,但需要涉及到JVM的操作和指令;相比而言,Javassist要简单的多,完全是基于Java的API,但其性能相比前二者要差一些。

尽管如此,在性能要求相对低的场合,Javassist仍然十分有用,如JBoss中就调用了Javassist。

Javassist的官方网站如下:

http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/

如下的链接是一个很好的Javassist代码示例:

http://yonglin4605.iteye.com/blog/1396494

如下的链接深入研究了Javassist中的一些语法,其中第8小节处对参数形式的总结很有作用:

http://zhxing.iteye.com/blog/1703305

如下的链接是IBM DW关于Javassist一个较为完整的教程:

http://www.ibm.com/developerworks/cn/java/j-dyn0916/

如下的代码是动态创建Java类二进制字节码并通过反射调用的示例,可供参考:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtNewMethod;
import javassist.Modifier;
import javassist.NotFoundException;
import javassist.CtField.Initializer;

public class JavassistGenerator {
	
	public static void main(String[] args) throws CannotCompileException, NotFoundException, InstantiationException, IllegalAccessException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
		// 创建类
		ClassPool pool = ClassPool.getDefault();
		CtClass cls = pool.makeClass("cn.ibm.com.TestClass");
		
		// 添加私有成员name及其getter、setter方法
		CtField param = new CtField(pool.get("java.lang.String"), "name", cls);
		param.setModifiers(Modifier.PRIVATE);
		cls.addMethod(CtNewMethod.setter("setName", param));
		cls.addMethod(CtNewMethod.getter("getName", param));
		cls.addField(param, Initializer.constant(""));
		
		// 添加无参的构造体
		CtConstructor cons = new CtConstructor(new CtClass[] {}, cls);
		cons.setBody("{name = \"Brant\";}");
		cls.addConstructor(cons);
		
		// 添加有参的构造体
		cons = new CtConstructor(new CtClass[] {pool.get("java.lang.String")}, cls);
		cons.setBody("{$0.name = $1;}");
		cls.addConstructor(cons);
		
		// 打印创建类的类名
		System.out.println(cls.toClass());
		
		// 通过反射创建无参的实例,并调用getName方法
		Object o = Class.forName("cn.ibm.com.TestClass").newInstance();
		Method getter = o.getClass().getMethod("getName");
		System.out.println(getter.invoke(o));
		
		// 调用其setName方法
		Method setter = o.getClass().getMethod("setName", new Class[] {String.class});
		setter.invoke(o, "Adam");
		System.out.println(getter.invoke(o));
		
		// 通过反射创建有参的实例,并调用getName方法
		o = Class.forName("cn.ibm.com.TestClass").getConstructor(String.class).newInstance("Liu Jian");
		getter = o.getClass().getMethod("getName");
		System.out.println(getter.invoke(o));
	}

}


最后需要特别注意的是:

1.      Javassist不支持要创建或注入的类中存在泛型参数

2.      Javassist对@类型的注解(Annotation)只支持查询,不支持添加或修改

版权声明:本文为博主原创文章,未经博主允许不得转载。

Java动态编程之javassist

概述  Javassist是一款字节码编辑工具,可以直接编辑和生成Java生成的字节码,以达到对.class文件进行动态修改的效果。熟练使用这套工具,可以让Java编程更接近与动态语言编程。教程mav...
  • FX_SKY
  • FX_SKY
  • 2016年06月19日 00:32
  • 2769

javassist入门

javassist的基本功能Javassist是一个动态类库,可以用来检查、”动态”修改以及创建 Java类。其功能与jdk自带的反射功能类似,但比反射功能更强大。重要的类ClassPool:java...
  • bjo2008cn
  • bjo2008cn
  • 2016年12月09日 19:33
  • 1269

javassist 介绍和使用

Javassist是一个执行字节码操作的强而有力的驱动代码库。它允许开发者自由的在一个已经编译好的类中添加新的方法,或者是修改已有的方法。但是, 和其他的类似库不同的是,Javassist并不要求开发...
  • sunny_sailor
  • sunny_sailor
  • 2013年01月15日 12:59
  • 4186

javassist使用中遇到的问题记录

Javassit提供了运行时操作Java字节码的方法,其效率低于asm。javassist主要是提供了代码级别的修改(也有bytecode级别),相比与asm的字节码级别的修改,学习成本低,开发效率高...
  • youaremoon
  • youaremoon
  • 2016年03月01日 11:07
  • 2049

Javassist的动态代理实现。

一提到jdk中的java.lang.reflect.Proxy,用过spring,hibernate等框架的人应该都有所了解,对!就是动态代理。AOP - 面向切面编程 - 就是基于动态代理实现的。 ...
  • mingxin95
  • mingxin95
  • 2016年07月02日 12:00
  • 1660

javassist 常用方法整理

javassist简介 一个比较好的例子:http://yucaifu1989.iteye.com/blog/1850500 比较好的文档:http://blog.csdn.net/u011425...
  • qq_24209665
  • qq_24209665
  • 2017年07月20日 14:27
  • 196

java javassist使用实例

package foo; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import javas...
  • earbao
  • earbao
  • 2015年08月27日 16:01
  • 1655

Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

本文阐述:class 文件 和代码中的class 对象之间的关系;动态代理中Invocation Handler角色的由来;Javassist 和ASM框架生成字节码;类加载器...
  • u010349169
  • u010349169
  • 2014年06月03日 15:48
  • 44679

Javassist详解

1. 简介 在博客中我们有提到关于Java反射,Java反射可以实现运行时加载,探知,自省,使用编译期完全未知的classes,获悉其完整构造,并生成其实体对象,或对fields设值。 自审:通过...
  • xianymo
  • xianymo
  • 2015年06月25日 10:20
  • 3125

Javassist简单应用小结

概述   Javassist是一款字节码编辑工具,可以
  • mousebaby808
  • mousebaby808
  • 2014年07月11日 15:37
  • 20664
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Javassist学习总结
举报原因:
原因补充:

(最多只允许输入30个字)