Javassit使用&动态类

Javassist 介绍

Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态AOP框架。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

javassit 概念

Javassist中最为重要的是ClassPool,CtClass ,CtMethod 以及 CtField这几个类。
ClassPool:一个基于HashMap实现的CtClass对象容器,其中键是类名称,值是表示该类的CtClass对象。默认的ClassPool使用与底层JVM相同的类路径,因此在某些情况下,可能需要向ClassPool添加类路径或类字节。

CtClass: (compile-time class) 表示一个类,这些CtClass对象可以从ClassPool获得。

CtMethods:表示类中的方法。

CtFields :表示类中的字段。

简单示例

ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("test.Rectangle");
cc.setSuperclass(pool.get("test.Point"));
cc.writeFile();

这个程序首先获得一个ClassPool对象,它用Javassist控制字节码修改。ClassPool对象是表示类文件的CTClass对象的容器。它根据需要读取一个类文件来构造一个CTClass对象,并记录所构造的对象以供以后响应访问。要修改类的定义,用户必须首先从ClassPool对象获取对表示该类的CTClass对象的引用。类池中的get()用于此目的。对于上面所示的程序,CTClass对象表示一个类测试。矩形是从ClassPool对象获得的,它被分配给一个变量cc。getdefault()返回的classpool对象搜索默认的系统搜索路径。

动态代码示例

以下是动态生成类并运行动态生成的方法:

package com.robin.assist;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
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.CtMethod;
import javassist.CtNewConstructor;
import javassist.CtNewMethod;
import javassist.NotFoundException;
import javassist.bytecode.AccessFlag;

public class DynamicGenerateClass {

	public static void main(String[] args) {
		
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.makeClass("com.robin.assit.test.Retangle");// 创建类
		cc.setInterfaces(new CtClass[] { pool.makeInterface("java.lang.Cloneable") });// 让类实现Cloneable接口
		try {
			CtField f = new CtField(CtClass.intType, "id", cc);
			// 生成一个int 类型的id属性
			f.setModifiers(AccessFlag.PUBLIC);// 设置访问修饰符
			cc.addField(f);// 将属性设置到类上
			// 添加构造方法
			CtConstructor constructor = CtNewConstructor.make("public Retangle(int id){this.id=id;}", cc);
			cc.addConstructor(constructor);
			// 添加方法
			CtMethod alohaMethod = CtNewMethod
					.make("public void aloha(String hello){" + "System.out.println(hello);" + "}", cc);
			cc.addMethod(alohaMethod);

			// 将生成的.class 文件保存到磁盘
			//cc.writeFile();

			//验证结果
			Class ct=cc.toClass();
			Field[] fields = ct.getFields();
			System.out.println("attribute name:" + fields[0].getName() + ",attribute type:" + fields[0].getType());
			Method aloha=ct.getMethod("aloha",new Class[] {String.class});
			
			//动态调用
			Constructor<?> con=ct.getConstructor(int.class);
			aloha.invoke(con.newInstance(1), "hello world");
			
		
		} catch (CannotCompileException e) {			
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
				e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {	
			e.printStackTrace();
		} catch (InstantiationException e) {			
			e.printStackTrace();
		}

	}
}

输出结果

attribute name:id,attribute type:int
hello world

http://www.javassist.org/tutorial/tutorial.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

robin-cloud

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值