已有的一个java bean 类 src下 同一包中
package xidian.lili.test.javassist;
public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
操作
package xidian.lili.test.javassist;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;
public class Demo02 {
public static void test01() throws NotFoundException, IOException, CannotCompileException{
/**
* 处理类的基本用法
*/
ClassPool pool=ClassPool.getDefault();
//获得已有类
CtClass cc=pool.get("xidian.lili.test.javassist.Person");
//获取字节码
byte[] bytes=cc.toBytecode();
System.out.println(Arrays.toString(bytes));
System.out.println(cc.getName());//xidian.lili.test.javassist.Person
System.out.println(cc.getSimpleName());//Person
System.out.println(cc.getModifiers());//1
System.out.println(cc.getSuperclass());
System.out.println(cc.getPackageName());//xidian.lili.test.javassist
}
public static void test02() throws NotFoundException, CannotCompileException, Exception, IllegalArgumentException, InvocationTargetException {
/**
* 处理方法的基本用法
*/
ClassPool pool=ClassPool.getDefault();
//获得已有类
CtClass cc=pool.get("xidian.lili.test.javassist.Person");
//第一种创建新方法
/*
CtMethod m1=CtMethod.make("int add(int a,int b){System.out.println(a+b);return a+b;}", cc);
*/
//第二种创建新方法 返回值类型 方法名 参数 对象
CtMethod m1=new CtMethod(CtClass.intType,"add",
new CtClass[]{CtClass.intType,CtClass.intType}, cc);
m1.setModifiers(Modifier.PUBLIC);
//[source error] no such field:
a找不到参数a 字节码的方式统一读入 不知道哪个是a 需要占位符$1第一个参数 $2第二个参数$0this
//m1.setBody("{System.out.println(a+b);return a+b;}");
m1.setBody("{System.out.println($1+$2);return $1+$2;}");
cc.addMethod(m1);
//通过反射调用新方法
Class c1=cc.toClass();
Person p=(Person) c1.newInstance();
Method m=c1.getDeclaredMethod("add", int.class,int.class);
m.invoke(p, new Object[]{3,4});
}
public static void test03() throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
/**
* AOP操作 对已有方法进行修改
*/
ClassPool pool=ClassPool.getDefault();
CtClass cc=pool.get("xidian.lili.test.javassist.Person");
CtMethod m2=cc.getDeclaredMethod("setName");
m2.insertBefore("{System.out.println(\"准备修改名字\");}");
m2.insertAfter("{System.out.println(\"修改名字完成\");}");
//通过反射调用
Class s=cc.toClass();
Object obj=s.newInstance();
Method m=s.getDeclaredMethod("setName",String.class);
m.invoke(obj, "lili");
}
public static void test04() throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
/**
* 对于属性的操作
* 添加新的属性
* 生成setter getter方法
*/
ClassPool pool=ClassPool.getDefault();
CtClass cc=pool.get("xidian.lili.test.javassist.Person");
//第一种
//CtField f2=CtField.make("private String school;", cc)
//第二种
CtField f1=new CtField(pool.get("java.lang.String"), "school", cc);
f1.setModifiers(Modifier.PRIVATE);
cc.addField(f1);
//生成setter getter方法 可以用生成Method方法来做或者如下
cc.addMethod(CtNewMethod.getter("getSchool", f1));
cc.addMethod(CtNewMethod.setter("setSchool", f1));
//通过反射调用
Class c=cc.toClass();
Object o=c.newInstance();
Method m=c.getDeclaredMethod("setSchool", String.class);
m.invoke(o,"西电");
Field f=c.getDeclaredField("school");
//System.out.print(f.get(o));//错误 属性是私有的 本能调用
f.setAccessible(true);
System.out.print(f.get(o));
}
/**
* 对构造器操作类似于普通方法
*
* CtConstructor []cons=cc.getConstructors();
* 对于注解的操作
* Object [] annos=cc.getAnnotations();
* 获取全部注解
*
*/
public static void main(String[] args) throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
//test01();
//test02();
//test03();
test04();
}
}